我正在写一个玩具程序来帮助我理解障碍是如何运作的。在程序中,我让每个线程检查一个数组中的元素是否位于另一个数组中。我能够让所有线程同时开始搜索,但我希望它们在过滤后都能在一起,以便正确地将任何数字添加到数组中。
如果不这样做,可能会将错误的数字添加到数组中。
编辑:有人建议我将pthread_barrier_wait(&after_filtering)添加到对filter_threads的调用中,这似乎很有用。现在我知道我必须在main和filter函数中添加一个等待调用,但是我不太明白执行的流程以及等待调用是如何在主要工作中进行的。我知道线程函数中的等待确保所有线程在继续之前都到达那个点,但是这不是在线程创建之后就发生了吗?这意味着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);
}我试着在过滤之后添加另一个等待调用,但现在程序只是挂起。我怎样才能做到这一点?
发布于 2018-11-18 22:09:04
屏障只是确保所有N个线程在继续之前到达代码中某个点的一种机制。因此,如果使用计数为4调用pthread_barrier_init,那么在同一个屏障上调用pthread_barrier_wait的任何线程都不会继续,直到其他三个线程也调用了pthread_barrier_wait。
因此,正如您的代码现在所提供的:三个创建的线程一旦启动,将执行pthread_barrier_wait(&before_filtering),在这里它们都将被阻塞,直到主线程执行了sleep(3),然后初始化了nums数组。然后主线程调用pthread_barrier_wait(&before_filtering)。这将释放主线程和所有其他线程以继续执行。
在执行filter函数之后,每个子线程和主线程都应该执行pthread_barrier_wait(&after_filtering).否则,主线程将陷入停滞,等待其他三个线程在屏障上等待。
尽管如此,根本没有必要使用第二个障碍。此时,主线程实际上只是在等待其他三个线程完成其任务并退出。主线程在每个子线程上执行的pthread_join完成相同的任务:即线程上的pthread_join在该线程完成执行之前不会返回。
https://stackoverflow.com/questions/53365649
复制相似问题