pthread_cond_broadcast 的意外行为
Unexpected behaviour of pthread_cond_broadcast
基于我昨天的问题 here,我编写了一个小代码示例,它启动了一些计数和一些等待线程。
等待线程停止 pthread_cond_wait
直到它们收到信号。计数线程完成任务后发送信号。
等待线程接收到它们的信号,每个线程打印出其给定的唯一 ID。
我希望所有等待的线程同时收到信号,以便它们中的每一个都可以继续执行程序。但是我注意到,输出并不混乱,事实上它们甚至看起来相当有序,就像在 FILO 中一样!
现在有很多地方我可能出错了。
这是我的代码:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define counting_threads 100
#define waiting_threads 100
int count = 0;
int counting_thread_ids[counting_threads];
int waiting_thread_ids[waiting_threads];
pthread_mutex_t count_mutex;
pthread_cond_t count_threshold_cv;
void init_ids(){
for(int i = 0; i < counting_threads; i++)
counting_thread_ids[i] = 2*i;
for(int j =0; j < waiting_threads; j++)
waiting_thread_ids[j] = 2*j+1;
}
void counting(void *t)
{
pthread_mutex_lock(&count_mutex);
count++;
if (count == counting_threads) {
sleep(2);
printf("inc_count(): count = %d Threshold reached. Signaling waiting threads. \n", count);
//~ pthread_cond_signal(&count_threshold_cv);
pthread_cond_broadcast(&count_threshold_cv);
}
pthread_mutex_unlock(&count_mutex);
}
void *waiting(void *t)
{
long my_id = (long)t;
//~ printf("Starting watch_count(): thread %ld\n", my_id);
pthread_mutex_lock(&count_mutex);
//~ printf("watch_count(): I start waiting now: %ld \n", my_id);
pthread_cond_wait(&count_threshold_cv, &count_mutex);
printf("watch_count(): thread %ld Condition signal received.\n", my_id);
pthread_mutex_unlock(&count_mutex);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
init_ids();
pthread_t wt[waiting_threads];
pthread_t ct[counting_threads];
/* Initialize mutex and condition variable objects */
pthread_mutex_init(&count_mutex, NULL);
pthread_cond_init (&count_threshold_cv, NULL);
for(int i = 0; i < waiting_threads; i++)
pthread_create(&wt[i], NULL, waiting, (void*) waiting_thread_ids[i] );
for(int i = 0; i < counting_threads; i++)
pthread_create(&ct[i], NULL, counting, (void*) counting_thread_ids[i] );
/* Wait for all threads to complete */
for (int i=0; i<waiting_threads; i++) {
pthread_join(wt[i], NULL);
}
for (int i=0; i<counting_threads; i++) {
pthread_join(ct[i], NULL);
}
/* Clean up and exit */
pthread_mutex_destroy(&count_mutex);
pthread_cond_destroy(&count_threshold_cv);
pthread_exit(NULL);
}
pthread_cond_signal() 调用解除阻塞至少一个在指定条件变量 cond 上阻塞的线程(如果任何线程在 cond 上阻塞)。
pthread_cond_broadcast() 调用取消阻塞当前在指定条件变量 cond 上阻塞的所有线程。
如果一个以上的线程在一个条件变量上被阻塞,调度策略决定线程被解除阻塞的顺序。
可以找到有关调度策略的更多信息here。
基于我昨天的问题 here,我编写了一个小代码示例,它启动了一些计数和一些等待线程。
等待线程停止 pthread_cond_wait
直到它们收到信号。计数线程完成任务后发送信号。
等待线程接收到它们的信号,每个线程打印出其给定的唯一 ID。
我希望所有等待的线程同时收到信号,以便它们中的每一个都可以继续执行程序。但是我注意到,输出并不混乱,事实上它们甚至看起来相当有序,就像在 FILO 中一样!
现在有很多地方我可能出错了。
这是我的代码:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define counting_threads 100
#define waiting_threads 100
int count = 0;
int counting_thread_ids[counting_threads];
int waiting_thread_ids[waiting_threads];
pthread_mutex_t count_mutex;
pthread_cond_t count_threshold_cv;
void init_ids(){
for(int i = 0; i < counting_threads; i++)
counting_thread_ids[i] = 2*i;
for(int j =0; j < waiting_threads; j++)
waiting_thread_ids[j] = 2*j+1;
}
void counting(void *t)
{
pthread_mutex_lock(&count_mutex);
count++;
if (count == counting_threads) {
sleep(2);
printf("inc_count(): count = %d Threshold reached. Signaling waiting threads. \n", count);
//~ pthread_cond_signal(&count_threshold_cv);
pthread_cond_broadcast(&count_threshold_cv);
}
pthread_mutex_unlock(&count_mutex);
}
void *waiting(void *t)
{
long my_id = (long)t;
//~ printf("Starting watch_count(): thread %ld\n", my_id);
pthread_mutex_lock(&count_mutex);
//~ printf("watch_count(): I start waiting now: %ld \n", my_id);
pthread_cond_wait(&count_threshold_cv, &count_mutex);
printf("watch_count(): thread %ld Condition signal received.\n", my_id);
pthread_mutex_unlock(&count_mutex);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
init_ids();
pthread_t wt[waiting_threads];
pthread_t ct[counting_threads];
/* Initialize mutex and condition variable objects */
pthread_mutex_init(&count_mutex, NULL);
pthread_cond_init (&count_threshold_cv, NULL);
for(int i = 0; i < waiting_threads; i++)
pthread_create(&wt[i], NULL, waiting, (void*) waiting_thread_ids[i] );
for(int i = 0; i < counting_threads; i++)
pthread_create(&ct[i], NULL, counting, (void*) counting_thread_ids[i] );
/* Wait for all threads to complete */
for (int i=0; i<waiting_threads; i++) {
pthread_join(wt[i], NULL);
}
for (int i=0; i<counting_threads; i++) {
pthread_join(ct[i], NULL);
}
/* Clean up and exit */
pthread_mutex_destroy(&count_mutex);
pthread_cond_destroy(&count_threshold_cv);
pthread_exit(NULL);
}
pthread_cond_signal() 调用解除阻塞至少一个在指定条件变量 cond 上阻塞的线程(如果任何线程在 cond 上阻塞)。
pthread_cond_broadcast() 调用取消阻塞当前在指定条件变量 cond 上阻塞的所有线程。
如果一个以上的线程在一个条件变量上被阻塞,调度策略决定线程被解除阻塞的顺序。
可以找到有关调度策略的更多信息here。