有没有其他同步方式

Is there an alternative way to sync

是否有其他方法可以确保线程已准备好接收广播信号。我想替换 main 中的 Sleep(1) 函数。

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

#define NUM 4


using namespace std;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_t tid[NUM];


void *threads(void *arg){
    int tid = (int)arg;
    while(true){
        pthread_mutex_lock(&mutex);
        pthread_cond_wait(&cond,&mutex);
        //do some work
        cout<<"Thread: "<<tid<<endl;;
        pthread_mutex_unlock(&mutex);
    }
}

int main(){

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

    Sleep(1);
    pthread_cond_broadcast(&cond);

    Sleep(1);
    pthread_cond_broadcast(&cond);

    Sleep(1);
    pthread_cond_broadcast(&cond);

    return 0;
}

我在 pthread_cond_wait 之前尝试过内存屏障,我想过使用计数器,但还没有任何效果。

条件变量通常连接到谓词。在其他线程中,检查谓词是否已经满足(检查同时持有保护谓词的互斥锁),如果是,则不要等待条件变量。在 main 中,获取互斥锁,持有互斥锁的同时改变谓词。然后释放互斥量并在 condvar 上发出信号或广播。这是一个类似的问题: Synchronisation before pthread_cond_broadcast

下面是一些示例代码:

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

#include <cassert>

#define NUM 4
#define SIZE 256


using std::cout;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_t tid[NUM];

int work_available;

void *threads(void *arg)
{
    int tid = *((int*)arg);
    while (1) {
        pthread_mutex_lock(&mutex);
        while (work_available == 0) {
            // While loop since cond_wait can have spurious wakeups.                                                                                                                                                                                                                                                                                                                        
            pthread_cond_wait(&cond, &mutex);
            cout << "Worker " << tid << " woke up...\n";
            cout << "Work available: " << work_available << '\n';
        }
        if (work_available == -1) {
            cout << "Worker " << tid << " quitting\n";
            pthread_mutex_unlock(&mutex); // Easy to forget, better to use C++11 RAII mutexes.                                                                                                                                                                                                                                                                                              
            break;
        }
        assert(work_available > 0);
        work_available--;
        cout << "Worker " << tid << " took one item of work\n";
        pthread_mutex_unlock(&mutex);

        //do some work                                                                                                                                                                                                                                                                                                                                                                      
        sleep(2); // simulated work                                                                                                                                                                                                                                                                                                                                                         
        pthread_mutex_lock(&mutex);
        cout << "Worker " << tid << " done with one item of work.\n";
        pthread_mutex_unlock(&mutex);
    }
}


int main()
{
    work_available = 0;

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

    const int MAX_TIME = 10;
    for (int i = 0; i < MAX_TIME; i++)
    {
        pthread_mutex_lock(&mutex);
        work_available++;
        cout << "Main thread, work available: " << work_available << '\n';
        pthread_mutex_unlock(&mutex);
        pthread_cond_broadcast(&cond);
        sleep(1);
    }

    pthread_mutex_lock(&mutex);
    cout << "Main signalling threads to quit\n";
    work_available = -1;
    pthread_mutex_unlock(&mutex);
    pthread_cond_broadcast(&cond);

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

    }
    return 0;
}