在c中使用条件变量
using condition variable in c
我有一个用 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
一个问题是您的生产者线程在将 avail
设置为 1 之前不验证它是否为零。当条件广播时,不能保证等待的消费者线程立即甚至首先得到调度。当它被调度时,它仍然必须首先锁定它在开始等待时放弃的互斥量。生产者的循环完全有可能在此之前运行几次。
如果你想在生产后强制消费,你应该让生产者检查 avail
-able 的东西是否已经被消费,对于 example 通过写你的循环如下:
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);
}
我有一个用 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
一个问题是您的生产者线程在将 avail
设置为 1 之前不验证它是否为零。当条件广播时,不能保证等待的消费者线程立即甚至首先得到调度。当它被调度时,它仍然必须首先锁定它在开始等待时放弃的互斥量。生产者的循环完全有可能在此之前运行几次。
如果你想在生产后强制消费,你应该让生产者检查 avail
-able 的东西是否已经被消费,对于 example 通过写你的循环如下:
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);
}