使用pthread_cond_wait和pthread_cond_signal保证屈服

假设我有一个带有3个POSIX线程的C程序,共享一个全局变量,互斥量和条件变量,其中两个执行以下伪代码:

...process data... pthread_mutex_lock( &mutex ); variable = data_ptr; pthread_cond_signal( &cond ); pthread_mutex_unlock( &mutex ); 

第三次运行:

 while(1) { while( variable == NULL ) { pthread_mutex_wait( &cond, &mutex ); } printf( "Data is %d", *variable ); } 

假设第三个线程将看到前两个中的每一个的数据是否安全?

换句话说,如果一个线程在互斥锁和一个条件变量上作用,是否可以安全地假设它是下一个获取锁定的信号,而不是一个其他可能正在等待的线程。锁?

没有pthread_mutex_wait这样的东西。 我猜你的意思是:

 pthread_mutex_lock(&mutex); /* ... */ while (1) { while (variable == NULL) pthread_cond_wait(&cond, &mutex); printf("Data is %d", *variable); } /* ... */ pthread_mutex_unlock(&mutex); 

没有保证第三个线程会看到两者的数据。 pthread_cond_signal将唤醒第三个线程,但它可能不会立即使用互斥锁。 其他作家之一可能首先使用互斥锁。 但是你可以用更多的工作来实现你想要的东西:

 void put(int *p) { pthread_mutex_lock(&mutex); while (variable) pthread_cond_wait(&cond_empty, &mutex); variable = p; pthread_cond_signal(&cond_full); pthread_mutex_unlock(&mutex); } int *get() { int *ret; pthread_mutex_lock(&mutex); while (!variable) pthread_cond_wait(&cond_full, &mutex); ret = variable; variable = NULL; pthread_cond_signal(&cond_empty); pthread_mutex_unlock(&mutex); return ret; } 

通过显式等待读取变量,我们避免了潜在的竞争条件。

这是我在标准中找到的内容:

4.13调度策略

调度策略会影响进程或线程排序:

[…]

  • 当进程或线程是一个被阻塞的线程并且它成为一个可运行的线程时

合规实现应定义每个调度策略可以修改优先级的方式,或者以其他方式影响上面列出的每个事件的进程或线程的排序。 此外,符合实现应定义其他情况以及每种调度策略可以以何种方式修改优先级或影响进程或线程的顺序。

所以它显然是未定义的。 这并不奇怪:一般来说,您无法假设将运行哪个可运行线程。

根据pthread_cond_wait

未阻塞的线程将根据调度策略(如果适用)竞争互斥锁,并且好像每个都调用了pthread_mutex_lock ()。

不幸的是,据我所知,没有可用的调度策略可以为您提供所需的行为。