0

I have been implementing Strassen algorithm with threads. I have passed data to threads by structures and launching them by function pthread_create() . The problem is I'm operating on std::vector < std::vector<int> > and I can't pass this to structure by reference. I have done some research and decided to use std::ref to wrap content and send it to function. The problem begins after exiting the function; r1 value does not change (inside changes), so there is something incorrect.

Example code:

typedef struct threadData
{
    int n;
    std::vector< std::vector<int> > mat1;
    std::vector< std::vector<int> > mat2;
    std::vector< std::vector<int> > result;
}thread_Data;



/* function adding 2 matrixes */

void *add_Thread(void *arg)
{
    thread_Data *data = (threadData*)arg;
    for (int i = 0; i < data->n; ++i)
    {
        for (int j = 0; j < data->n; ++j)
        {
            data->result[i][j] = data->mat1[i][j] + data->mat2[i][j];
        }
    }

    pthread_exit(0);
}

/* ... code ... */

thread_Data adds;
adds = thread_Data{newSize, a11, a22, std::ref(r1)};  // here passing by std::ref

pthread_t adder;

pthread_create(&adder, NULL, add_Thread, &adds[i]);

pthread_join(adder, NULL);

/* and r1 value does not change here */

How to fix it?

NOTE: *add_Thread() works fine; I use array in my program. The code here is only to show idea.

kjtn99
  • 51
  • 1
  • 8
  • 2
    `std::ref` doesn't magically make a non-reference a reference. `thread_Data::result` is not a reference. Also note that `typedef struct` is not required in C++. Just use `struct thread_Data`. I'm also not sure `&adds[i]` is doing what you think it's doing... `adds` is not an array. – cdhowie Jun 19 '20 at 19:37
  • Any reason you aren't using `std::thread`? It knows about `std::reference_wrapper`'s and handles them correctly. – NathanOliver Jun 19 '20 at 19:38
  • Yes it is not an array here. But in my program is. I just wanted to do a shortcut – kjtn99 Jun 19 '20 at 19:40
  • @NathanOliver I'm beginner in threads – kjtn99 Jun 19 '20 at 19:48
  • 2
    That's even more of a reason to use `std::thread`. It works with the type system, so no void pointers and casting has to be done. – NathanOliver Jun 19 '20 at 19:49
  • @NathanOliver sure, I have to try it. But this is the only problem that bothers me. If I fix it, my project would be finished. Using std::thread I have to do too much work for now. But if nothing helps, I will do it. – kjtn99 Jun 19 '20 at 19:53
  • @cdhowie so is here any way to deal with passing r1 to structure? Changing variable result type to reference? :d – kjtn99 Jun 19 '20 at 19:55
  • @kjtn99 You could simply make `result` a pointer. – cdhowie Jun 19 '20 at 19:57
  • @cdhowie I'm confused. Pointers are not my favourite things :D. New type should be std::vector< std::vector > * ? – kjtn99 Jun 19 '20 at 20:04
  • @kjtn99 Yes. If you are going to assign one `thread_Data` object to another then you can't use references as they can't be reseated. – cdhowie Jun 19 '20 at 20:07
  • @cdhowie Then what should I change in loop in function adding matrixes? Types will be different – kjtn99 Jun 19 '20 at 20:13
  • @kjtn99 For simpler access, after `thread_Data *data = (threadData*)arg;` you could add `auto & result = *(data->result);` then just use `result` instead of `data->result` everywhere else. – cdhowie Jun 19 '20 at 20:18
  • 2) error: cannot convert ‘std::reference_wrapper > >’ to ‘std::vector >*’ in initialization adds[0] = thread_Data{newSize, a11, a22, std::ref(r1)}; – kjtn99 Jun 19 '20 at 20:28
  • @kjtn99 Of course, because `std::ref` isn't appropriate there (which we already said). Use `&r1`. – cdhowie Jun 19 '20 at 20:34
  • Oh man, dummy me. Everything works. Thank You bro !! – kjtn99 Jun 19 '20 at 20:35
  • @kjtn99 No problem! – cdhowie Jun 19 '20 at 20:39

0 Answers0