簡體   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