繁体   English   中英

使用pthread和同步

[英]Working with pthreads and synchronization

我正在编写一个玩具程序,以帮助我理解障碍的工作原理。 在程序中,我每个线程都要检查一个数组中的元素是否在另一个数组中。 我能够让所有线程同时开始搜索,但是我想让它们在过滤之后全部聚在一起,以便正确地将任何数字添加到数组中。

否则,可能会将错误的数字添加到数组中。

编辑:有人建议我添加pthread_barrier_wait(&after_filtering); 在调用filter_threads时,这似乎可以解决问题。 现在我知道我必须在main和filter函数中添加一个等待调用,但是我不太了解执行的流程以及等待调用在main中的工作方式。 我知道线程函数中的等待可确保所有线程在继续之前达到该点,但是那不是在创建线程后立即发生吗? 意味着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);
}

我尝试在过滤后添加另一个等待调用,但是现在程序挂起了。 我该怎么做?

屏障只是一种机制,可确保所有N个线程在继续操作之前到达代码中的特定点。 因此,如果你调用pthread_barrier_init为4的计数,任何线程调用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才会返回。

暂无
暂无

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

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