简体   繁体   中英

Working with pthreads and synchronization

I'm writing a toy program to help me understand how barriers work. In the program I have each thread checking to see if an element in one array is in another array. I was able to have all threads start searching simultaneously but I'd like to have them all meet up after filtering in order to correctly add any numbers to the array.

Without doing so, the the wrong numbers might be added to the array.

EDIT: Someone suggested I'd add pthread_barrier_wait(&after_filtering); in the call to filter_threads and that seemed to do trick. Now I know that I have to add a wait call in main as well as in the filter function, but I don't quite understand the flow of execution and how the wait calls in main work. I know that the wait in the thread function ensures that all threads reach that point before continuing but doesn't that happen as soon as the threads created? Meaning that nums should have values of 99 instead of 4, 3, 8, 1?

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

pthread_barrier_t before_filtering, after_filtering;
int nums[4] = {99, 99, 99, 99};
int arr[15] = {12, 5, 31, 8, 1, 6, 24, 4, 81, 42};

void filter(int i, int a[]){
    // Loop through the list
    int j;
    for (j = 0; j < 10; j++)
    {
        if (nums[i] == a[j])
            nums[i] = 0; 
    }
}

void *filter_threads(void *id){
    int *myid = (int *)id;
    printf("thread %d\n",*myid);
    pthread_barrier_wait(&before_filtering);
    filter(*myid, arr);
    pthread_barrier_wait(&after_filtering);
}

int main(void)
{
    pthread_t tids[3];
    int index[3];
    pthread_barrier_init(&before_filtering, NULL, 4);
    pthread_barrier_init(&after_filtering, NULL, 4);
    int i, j;

    for (i = 0; i < 3; i++)
    {   
        index[i] = i + 1;
        pthread_create(&tids[i], NULL, filter_threads, &index[i]);
    }

    // Cannot call any filter function without first populating nums
    nums[0] = 4;
    nums[1] = 3;
    nums[2] = 8;
    nums[3] = 1;

    pthread_barrier_wait(&before_filtering);
    filter(0, arr);
    pthread_barrier_wait(&after_filtering);

    // Add new numbers to arr...

    printf("New nums: ");
    for (i = 0; i < 4; i++)
        printf("%d, ", nums[i]);
    printf("\n");

    for (i = 0; i < 3; i++)
        pthread_join(tids[i], NULL);

    // Print new arr...

    pthread_barrier_destroy(&before_filtering);
    pthread_barrier_destroy(&after_filtering);
}

I tried adding another wait call after the filtering but now the program just hangs. How can I accomplish this?

A barrier is simply a mechanism to ensure that all N threads reach a certain point in the code before continuing. Hence, if you call pthread_barrier_init with a count of 4, any thread calling pthread_barrier_wait on that same barrier will not continue until three other threads have also called pthread_barrier_wait .

So, as your code provides now: the three created threads will, once started, execute the pthread_barrier_wait(&before_filtering) where they will all block until after the main thread has executed sleep(3) and then initialized the nums array. The main thread then calls pthread_barrier_wait(&before_filtering) . This releases the main thread and all the others to continue execution.

After executing the filter function, each sub-thread and the main thread should execute pthread_barrier_wait(&after_filtering) . Otherwise, the main thread will be stalled waiting for three other threads to wait on the barrier.

That being said, there is no need to use the second barrier at all. At that point, the main thread is really just waiting for the other three threads to finish their task and quit. The pthread_join on each sub-thread being done by the main thread accomplishes the same thing: ie the pthread_join on a thread will not return until that thread has finish execution.

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