pthread_cond_broadcast之前的同步

时间:2017-03-10 15:17:03

标签: c++ synchronization pthreads

我想从主线程向所有等待条件的其他线程发送广播信号。在我看来,广播信号提前到线程。

#include <iostream>
#include <pthread.h>

#define NUM 4
#define SIZE 256

using namespace std;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_barrier_t barrier;

class cache{
    int lv1;
public:
    int write(int i){
        lv1=i;
        pthread_cond_broadcast(&cond);
    }
};

cache c[NUM];

void *thread(void *arg){
   int i = (int)arg;
   for(;;){
       pthread_mutex_lock(&mutex);
       pthread_cond_wait(&cond,&mutex);
       cout << "Thread: "<< i << endl;
       //do some work
       pthread_mutex_unlock(&mutex);
   }
}


int main()
{
    pthread_t tid[NUM];
    pthread_barrier_init(&barrier,NULL,NUM+1);

    for(int i=0;i<NUM;i++){
        pthread_create(&tid[i],NULL,thread,(void*)i);
    }

    //Sleep(2);
    c[0].write(55);  //broadcast signal
    //Sleep(2);
    c[1].write(44);  //broadcast signal

    for(int i=0;i<NUM;i++){
        pthread_join(tid[i],NULL);
    }

    cout << "Hello world!" << endl;
    return 0;
}

如果我在主函数中插入Sleep(2),它可以工作,但我不想在调用pthread_broadcast之前等待一段时间而是同步。 我想到了一个障碍,但是pthread_cond_wait正在阻塞,对吗?

2 个答案:

答案 0 :(得分:1)

您需要了解如何使用条件变量。您还错误地处理了线程的整数参数。这是一个固定版本,希望类似于你想要的版本:

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

#define NUM 4
#define SIZE 256

using namespace std;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_barrier_t barrier;

class cache{
    int lv1;
public:
    int write(int i) { lv1=i; }
    const int val() { return lv1; }
};

cache c[NUM];

void *thread(void *arg)
{
    int i = *(int*)arg;
    for(;;) {
        pthread_mutex_lock(&mutex);
        // Check predicate, do not go to sleep if predicate is fulfilled                                                                                                                                                                                                                                                                                                                    
        if (c[0].val() > 0 && c[1].val() > 0) {
            cout << "Thread " << i << " leaving...\n";
            pthread_mutex_unlock(&mutex);
            return 0;
        }
        pthread_cond_wait(&cond, &mutex);
        cout << "Thread wakeup: "<< i << endl;
        // do some work                                                                                                                                                                                                                                                                                                                                                                     
        pthread_mutex_unlock(&mutex);
    }
}


int main()
{
    pthread_t tid[NUM];

    int arg[NUM];
    for(int i=0; i<NUM; i++) {
        arg[i] = i; // make a copy of i used by only one thread                                                                                                                                                                                                                                                                                                                             
        pthread_create(&tid[i], NULL, thread,(void*)&arg[i]);
    }

    pthread_mutex_lock(&mutex);
    c[0].write(55);
    c[1].write(44);
    pthread_mutex_unlock(&mutex);
    pthread_cond_broadcast(&cond); // Signal all threads that predicate is fulfilled                                                                                                                                                                                                                                                                                                        


    for(int i=0; i<NUM; i++) {
        pthread_join(tid[i],NULL);
        cout << "Joined " << i << '\n';
    }

    cout << "Hello world!" << endl;
    return 0;
}

答案 1 :(得分:0)

Sequence how I think it is

这就是我现在的想法,在发送广播信号之前,我还需要一种同步方式。

在那张照片中,第一个pthread_broadcast太早了。