生产者消费者模型 1.多个线程操作全局变量n,需要做成临界区(要加锁--线程锁或者信号量) 2.调用函数pthread_cond_wait(&g_cond,&g_mutex)让这个线程锁在某一个条件上等待 --pthread_cond_wait()函数的本质是①:拿到锁的线程,把锁暂时丢掉(解锁)②:线程休眠,进行等待③:线程等待通知,醒来继续执行(重新获得锁) --这个pthread_cond_wait()函数是一个原子性操作 --注意:丢掉的锁可以被生产线程获得,也可以被消费线程获得,消费者线程获取会陷入等待,生产者线程获得会发送信号,唤醒消费者 3.pthread_cond_signal()生产者拿到锁,生产n,生产完成后,发送信号给消费者(唤醒消费者),生产者离开临界区
//生产者消费者模型 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <pthread.h> //定义线程锁 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //定义线程条件锁 pthread_cond_t cond = PTHREAD_COND_INITIALIZER; //定义全局变量 int g_num = 0; //定义消费者线程数量 #define Consume_Count 2 //定义生产者线程数量 #define Product_Count 4 //消费者线程 void *consume_run(void * arg) { int tnum = (int) arg; while (1) { //因为多线程操作一个全局变量,需要做成临界区,枷锁 pthread_mutex_lock(&mutex); printf("消费者%d进入临界区!\n", tnum); //因为就算消费者被唤醒,也需要重新检查g_num的值,因为pthread_cond_wait()函数丢锁之后,可能被其他消费者获得 //导致多个消费者线程都执行了pthread_cond_wait()函数陷入等待, //因为多个消费者线程被pthread_cond_signal()唤醒,但是资源只有一个,可能已经被其他消费者使用了 //pthread_cond_wait()也有可能被其他信号唤醒 //所以需要重新判断,而不能使用if while (g_num == 0) { printf("消费者%d开始等待!\n", tnum); //在该线程锁上,进行条件等待 pthread_cond_wait(&cond, &mutex); printf("消费者%d被唤醒!\n", tnum); } //表示已经有资源了,可以消费了 printf("消费者%d开始消费!\n", tnum); g_num--; //解锁 pthread_mutex_unlock(&mutex); sleep(3); } return NULL; } //生产者线程 void *product_run(void * arg) { int tnum = (int) arg; while (1) { //当生产者大于消费者时,可能出现生产过多的商品,需要对商品的上限做一个限制,如果商品过多,需要让生产者睡眠 //涉及到对全局变量的访问,需要加锁 printf("现有资源个数%d!\n",g_num); pthread_mutex_lock(&mutex); if (g_num > 20) { printf("生产者%d产品已经到达上限,进入睡眠!\n", tnum); //如果生产产品大于上限,需要睡眠,但是睡眠前应该将锁释放.,留给消费者进行消费 pthread_mutex_unlock(&mutex); sleep(3); continue; } else { printf("生产者%d生产产品!\n", tnum); //如果生产产品小于上限,那么不需要生产者睡眠,接着生产产品 g_num++; //发送条件信号 printf("生产者%d发送条件信号!\n", tnum); pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); } pthread_mutex_unlock(&mutex); sleep(2); } return NULL; } int main(int arg, char * args[]) { pthread_t thrs[Consume_Count + Product_Count]; int i = 0; for (i = 0; i < Consume_Count; i++) { if (pthread_create(&thrs[i], NULL, consume_run, (void *) i) != 0) { printf("pthread_create() failed !\n"); return -1; } } for (i = 0; i < Product_Count; i++) { if (pthread_create(&thrs[i + Consume_Count], NULL, product_run, (void *) i) != 0) { printf("pthread_create() failed !\n"); return -1; } } //join for (i = 0; i < Consume_Count + Product_Count; i++) { if (pthread_join(thrs[i], NULL) != 0) { printf("pthread_join() failed !\n"); break; } } printf("进程推出了!\n"); return 0; }
时间: 2024-10-04 08:24:29