简体   繁体   中英

How to make a memcpy inside of an thread of pthread?

I'm trying to do a sum of 2 matrices using pthreads in c++. I'm stuck at trying to pass the result of the sum calculated inside a thread to my main function.

The 2 values to be added are inside a struct:

struct sum{
    int value1;
    int value2;
    int result;
}typedef struct_sum;

And the struct containing the values is passed as an argument to pthread_create() so that the operation is excuted inside a thread.

Here's my routine:

void * routine(void * sum) {
    std::cout<<((struct_sum *)sum)->value1 + ((struct_sum *)sum)->value2<<std::endl;
    std::cout<<((struct_sum *)sum)->value1<<std::endl;
    std::cout<<((struct_sum *)sum)->value2<<std::endl;
    int i = (((struct_sum *) sum)->value1 + ((struct_sum *) sum)->value2);
//    memcpy(&(((struct_sum *)sum)->result), reinterpret_cast<const void *>(i), sizeof(i));
    ((struct_sum *)sum)->result = i;
    std::cout<<&(((struct_sum *)sum)->result)<<std::endl;
    pthread_exit(nullptr);
}

In the first 3 cout I check if my values are coming correctly to the thread. In the last cout (before exiting the thread) I check the memory address of the result element of the struct (so I can see that it has the same address inside the main function).

Here's the main function:

int main(int argc, char * argv[]) {
    int mat_1[ROW_SIZE][COLUMN_SIZE] = {{1, 2},
                                        {6, 7}};
    int mat_2[ROW_SIZE][COLUMN_SIZE] = {{3, 15},
                                        {9, 14}};
    int mat_result[ROW_SIZE][COLUMN_SIZE];
    int mat_size = sizeof(mat_1) / sizeof(int);
    int row_size = sizeof(mat_1) / sizeof(mat_1[0]);
    int column_size = sizeof(mat_1[0]) / sizeof(int);
    pthread_t threads[mat_size];
    int thread_number = 0;
    int thread_handler;
    for (int row = 0; row < row_size; row++) {
        for (int column = 0; column < column_size; column++) {
            struct_sum *result;
            result = static_cast<struct_sum *>(malloc(sizeof(struct_sum)));
            result->value1 = mat_1[row][column];
            result->value2 = mat_2[row][column];
            result->result = 0;
            thread_handler = pthread_create(&threads[thread_number], nullptr, routine, result);
            if(thread_handler) return(-1);
            std::cout << &(result->result)<<std::endl;
            thread_number++;
            mat_result[row][column] = result->result;
//            free(result);
        }
    }
    pthread_exit(nullptr);
}

I'm having two problems:

  1. Even though the result has the same address in the main and in the thread, when I copy the value of i to ((struct_sum *)sum)->result , in the main function, result->result is still 0.

  2. When I uncomment the memcpy() line the thread simply don't run, so I don't know how I'm doing it wrong.

I was expecting that in my main function the statement std::cout << (result->result) <<std::endl would return me the result of the operation, but the current value is 0.

So, how do I perform the memcpy() correctly in the thread?

You have to JOIN your threads. It means, wait them to finish. The way you were doing is basically starting the thread and not giving it a guaranteed time do to anything. Besides that, some important change to the API, check the comments below:

void * routine(void * sum) {
    int i = (((struct_sum *) sum)->value1 + ((struct_sum *) sum)->value2);
    ((struct_sum *)sum)->result = i;

    // notice you don't need memcpy(), in fact...
    // but you could use it here if you want... it won't fail.

    // you have to use this function so it return your result to the main thread.
    pthread_exit(sum);
}

int main(int argc, char * argv[]) {
    int mat_1[ROW_SIZE][COLUMN_SIZE] = {{1, 2},
                                        {6, 7}};
    int mat_2[ROW_SIZE][COLUMN_SIZE] = {{3, 15},
                                        {9, 14}};
    int mat_result[ROW_SIZE][COLUMN_SIZE];
    int mat_size = sizeof(mat_1) / sizeof(int);
    int row_size = sizeof(mat_1) / sizeof(mat_1[0]);
    int column_size = sizeof(mat_1[0]) / sizeof(int);
    pthread_t threads[mat_size];
    int thread_number = 0;
    int thread_handler;
    for (int row = 0; row < row_size; row++) {
        for (int column = 0; column < column_size; column++) {
            struct_sum *result;
            result = static_cast<struct_sum *>(malloc(sizeof(struct_sum)));
            result->value1 = mat_1[row][column];
            result->value2 = mat_2[row][column];
            result->result = 0;
            thread_handler = pthread_create(&threads[thread_number], nullptr, routine, result);
            if(thread_handler) return(-1);
            // std::cout << &(result->result)<<std::endl;
            thread_number++;
            // forget this line below
            // mat_result[row][column] = result->result;
        }
    }

    // here you wait for the threads to JOIN
    // here it means they actually "finished" their job
    for (int i = 0; i < mat_size; i++)
    {
        struct_sum *result;

        // here you wait for the threads to finish their job
        // add something to your struct to "identify" the thread, so
        // you can figure out where in the final matrix you put the result
        pthread_join(threads[i], (void**)&result);
        std::cout << result->result << "\n";

        // this will print the correct sums: 4, 17, 15 and 21
        // notice: it will be printed in ANY order, once you
        // don't know which thread will finish first
        // but result->result has the... result you need!
        // you have to figure out how to fit this result in your matrix.
        // but this is out of scope of the question
        // and you can do yourself. have fun! :-)

        // here you can free the result, you already got the value!
        free(result);
    }

    // you don't need this line below... this goes to routine()
    // pthread_exit(nullptr);
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM