我有一个用c++编写的多线程程序,它有3个线程、主线程、生产者线程和使用者线程。代码使用条件变量来处理信令和处理发出的信号。问题是,当我运行程序时,似乎有些发出的信号丢失了,没有被任何处理程序捕获。有人能给我解释一下这些输出吗?
全球变量:
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int avail = 0;生产者线:
static void *producer_thread(void *arg)
{
for (size_t i = 0; i < 10; i++)
{
pthread_mutex_lock(&mtx);
avail = 1;
// sleep(2);
pthread_mutex_unlock(&mtx);
pthread_cond_broadcast(&cond);
printf("sent signal#%ld from signaling thread\n", i);
}
pthread_exit(NULL);
}消费者线索:
static void *consumer_thread(void *arg)
{
while (1)
{
pthread_mutex_lock(&mtx);
while(0 == avail)
{
pthread_cond_wait(&cond, &mtx);
}
printf("received signal from consuming_thread\n");
avail = 0;
pthread_mutex_unlock(&mtx);
}
}主螺纹:
int main(int argc, char *argv[])
{
pthread_t tid1, tid2;
int rc;
rc = pthread_create(&tid1, NULL, consumer_thread, NULL);
if(rc){
printf("error in pthread_create form consuming_thread\n");
exit(-1);
}
rc = pthread_create(&tid2, NULL, producer_thread, NULL);
if(rc){
printf("error in pthread_create form signalling thread\n");
exit(-1);
}
pthread_exit(NULL);
}样本输出:
sent signal#0 from signaling thread
received signal from consuming_thread
sent signal#1 from signaling thread
sent signal#2 from signaling thread
sent signal#3 from signaling thread
sent signal#4 from signaling thread
sent signal#5 from signaling thread
sent signal#6 from signaling thread
sent signal#7 from signaling thread
sent signal#8 from signaling thread
received signal from consuming_thread
sent signal#9 from signaling thread
received signal from consuming_thread发布于 2021-09-19 14:39:25
一个问题是,在将avail设置为1之前,生产者线程不会验证它是否为零。当条件广播时,这并不能保证等待的使用者线程立即被调度,甚至是第一个。当它被调度时,它仍然必须首先锁定它在开始等待时放弃的互斥锁。在这种情况发生之前,生产者的循环完全有可能运行几次。
如果您想在生产之后强制消费,您应该让生产者检查是否已经使用了avail-able东西,例如编写如下循环:
for (size_t i = 0; i < 10; i++)
{
int proceed = 0;
while (!proceed) {
pthread_mutex_lock(&mtx);
if (avail == 0) {
avail = 1;
proceed = 1;
}
pthread_mutex_unlock(&mtx);
}
pthread_cond_broadcast(&cond);
printf("sent signal#%ld from signaling thread\n", i);
}https://stackoverflow.com/questions/69236549
复制相似问题