简体   繁体   English

使用pthread和同步

[英]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); 编辑:有人建议我添加pthread_barrier_wait(&after_filtering); in the call to filter_threads and that seemed to do trick. 在调用filter_threads时,这似乎可以解决问题。 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. 现在我知道我必须在main和filter函数中添加一个等待调用,但是我不太了解执行的流程以及等待调用在main中的工作方式。 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? 意味着num的值应为99,而不是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. 屏障只是一种机制,可确保所有N个线程在继续操作之前到达代码中的特定点。 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 . 因此,如果你调用pthread_barrier_init为4的计数,任何线程调用pthread_barrier_wait对同一屏障不会继续下去,直到其他三个线程也称为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. 因此,正如您的代码现在提供的那样:创建的三个线程一旦启动,将执行pthread_barrier_wait(&before_filtering) ,在所有线程都将阻塞之前,主线程执行sleep(3)然后初始化nums数组。 The main thread then calls pthread_barrier_wait(&before_filtering) . 然后,主线程调用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) . 在执行filter功能之后,每个子线程主线程应执行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. 由主线程完成的每个子线程上的pthread_join完成相同的操作:即,直到该线程完成执行,线程上的pthread_join才会返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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