简体   繁体   English

pthread_cond_broadcast之前的同步

[英]Synchronisation before pthread_cond_broadcast

I want to send a broadcast signal from the main thread to all the other threads waiting for a condition. 我想从主线程向所有其他等待条件的线程发送广播信号。 It seems to me that the broadcast signal comes to early to the threads. 在我看来,广播信号早早到达了线程。

#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;
}

If I insert Sleep(2) in the main function, it works, but I do not want to wait a time but a synchronisation before calling pthread_broadcast. 如果我在主函数中插入Sleep(2),它可以工作,但我不想在调用pthread_broadcast之前等待一段时间,而是等待同步。 I thought of a barrier, but pthread_cond_wait is blocking, right? 我想到了一个障碍,但是pthread_cond_wait正在阻止,对吗?

You need to read up on how condition variables are used. 您需要阅读如何使用条件变量。 You also handled the integer arguments to your threads erroneously. 您还错误地处理了线程的整数参数。 Here is a fixed version, hopefully similar to what you wanted: 这是一个固定版本,希望类似于您想要的版本:

#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;
}

Sequence how I think it is 顺序我认为是

This is how it is right now I think, I still need a way to synchronise, before I send the broadcast signal. 我认为现在就是这样,在发送广播信号之前,我仍然需要一种同步方法。

In that picture, the first pthread_broadcast comes too early. 在该图中,第一个pthread_broadcast来得太早了。

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

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