操作系统生产者消费者问题C语言
#include <stdio.h>
#include <pthread.h>
#include <windows.h>
#define N 100
#define true 1
#define producerNum 15
#define consumerNum 10
#define sleepTime 1000
typedef int semaphore;
typedef int item;
item buffer[N] = {0};
int in = 0;
int out = 0;
int proCount = 0;
semaphore mutex = 1, empty = N, full = 0, proCmutex = 1;
void * producer(void * a){
while(true){
while(proCmutex <= 0);
proCmutex--;
proCount++;
printf("生产一个产品ID%d, 缓冲区位置为%d\n",proCount,in);
proCmutex++;
while(empty <= 0){
printf("缓冲区已满!\n");
}
empty--; //P操作申请资源 -1
/*
mutex为1时,标识两个进程都未进入需要互斥的临界区,
为0时,一个进程进入临界区运行,另一个必须等待,挂入阻塞队列
为-1时,一个进程正在临界区运行,另一个在阻塞队列中
*/
while(mutex <= 0);
mutex--; //P操作,信号量 -1,避免同时访问缓冲池
buffer[in] = proCount; //将产品放入缓冲池
in = (in + 1) % N;
mutex++; //V操作释放资源 ,执行完毕,信号量 +1 ,缓冲池可访问
full++; //V操作
Sleep(sleepTime); //一个进程结束,休眠一定时间,以便观察
}
}
void * consumer(void *b){
while(true){
while(full <= 0){
printf("缓冲区为空!\n");
}
full--;
while(mutex <= 0);
mutex--;
int nextc = buffer[out];
buffer[out] = 0; //消费完将缓冲区设置为0
out = (out + 1) % N;
mutex++;
empty++;
printf("\t\t\t\t消费一个产品ID%d,缓冲区位置为%d\n", nextc,out);
Sleep(sleepTime);
}
}
int main()
{
pthread_t threadPool[producerNum+consumerNum];//创建线程池
int i;
for(i = 0; i < producerNum; i++){
pthread_t temp; //pthread_t 用来定义线程类型的变量
//pthread_create 用来创建线程四个参数(指向线程标识符的指针,线程属性(默认属性),函数起始地址,函数参数) 创建失败 -1
if(pthread_create(&temp, NULL, producer, NULL) == -1)
{
printf("ERROR, fail to create producer%d\n", i);
exit(1);
}
threadPool[i] = temp;
}//创建生产者进程放入线程池
for(i = 0; i < consumerNum; i++){
pthread_t temp;
if(pthread_create(&temp, NULL, consumer, NULL) == -1){
printf("ERROR, fail to create consumer%d\n", i);
exit(1);
}
threadPool[i+producerNum] = temp;
}//创建消费者进程放入线程池
void * result;
for(i = 0; i < producerNum+consumerNum; i++){
if(pthread_join(threadPool[i], &result) == -1){
printf("fail to recollect\n");
exit(1);
}
}//运行线程池
return 0;
}
生产者消费者问题主要是在线程调用的基础上多加了P、V操作。其中线程调用主要使用的是pthread。
Windows下使用Dev-C++开发基于pthread的多线程,步骤---->https://blog.csdn.net/qq_41681845/article/details/89715870
需要使用的函数主要是下面的四个函数
1、pthread_t:用来定义一个线程类型的变量
用法 pthread_t x1;
2、pthread_create:建立线程,它有4个参数
pthread_create(&temp, NULL, print_b, NULL);
第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。这里,我们的函数thread不需要参数,所以最后一个参数设为空指针。第二个参数我们也设为空指针,这样将生成默认属性的线程。
3、pthread_join:用来等待一个线程的结束,也可以理解为线程开始
第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。
pthread_join(threadPool[i], &result);
4、pthread_exit:一个线程的结束有两种途径,一种函数结束了,调用它的线程也就结束了;另一种方式是通过函数pthread_exit来实现
运行结果: