例如:有个全局变量gnum=0,线程1首先执行,内容是不停的自加gnum,当gnum > 5,线程1挂起,开始执行线程2,线程2不停的自减,直至gnum<5时,线程2挂起,开始执行线程1,两个线程不停的切换
3 个解决方案
#1
#2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
static int gnum = 0;
static int full = 0;
static int hungry = 0;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static void *proc1(void *arg)
{
while (1) {
pthread_mutex_lock(&lock);
while (gnum > 5) {
if (hungry)
pthread_cond_signal(&cond);
full = 1;
pthread_cond_wait(&cond, &lock);
}
full = 0;
++gnum;
printf("proc1 gnum=%d\n", gnum);
pthread_mutex_unlock(&lock);
}
return NULL;
}
static void *proc2(void *arg)
{
while (1) {
pthread_mutex_lock(&lock);
while (gnum < 5) {
hungry = 1;
if (full)
pthread_cond_signal(&cond);
pthread_cond_wait(&cond, &lock);
}
hungry = 0;
--gnum;
printf("proc2 gnum=%d\n", gnum);
pthread_mutex_unlock(&lock);
}
return NULL;
}
int main(int argc, char *const argv[])
{
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, proc1, NULL);
pthread_create(&tid2, NULL, proc2, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
#3
说明一下,full和hungry是防止多个生产者多个消费者情况下导致的signal自唤醒问题,重点是清楚signal只对当时正在wait的线程有效,那么多生产者多消费者情况下导致自唤醒问题就可以理解了。
#1
#2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
static int gnum = 0;
static int full = 0;
static int hungry = 0;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static void *proc1(void *arg)
{
while (1) {
pthread_mutex_lock(&lock);
while (gnum > 5) {
if (hungry)
pthread_cond_signal(&cond);
full = 1;
pthread_cond_wait(&cond, &lock);
}
full = 0;
++gnum;
printf("proc1 gnum=%d\n", gnum);
pthread_mutex_unlock(&lock);
}
return NULL;
}
static void *proc2(void *arg)
{
while (1) {
pthread_mutex_lock(&lock);
while (gnum < 5) {
hungry = 1;
if (full)
pthread_cond_signal(&cond);
pthread_cond_wait(&cond, &lock);
}
hungry = 0;
--gnum;
printf("proc2 gnum=%d\n", gnum);
pthread_mutex_unlock(&lock);
}
return NULL;
}
int main(int argc, char *const argv[])
{
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, proc1, NULL);
pthread_create(&tid2, NULL, proc2, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
#3
说明一下,full和hungry是防止多个生产者多个消费者情况下导致的signal自唤醒问题,重点是清楚signal只对当时正在wait的线程有效,那么多生产者多消费者情况下导致自唤醒问题就可以理解了。