生产者-消费者问题 ——by一宇 2021-01-04

生产者-消费者问题

1.1 整型信号量

1.1.1 Windows环境

直接运行如下代码即可

#include <stdio.h>
#include <pthread.h>//线程的创建
#include <windows.h>
#define N 100
#define true 1
#define producerNum  10
#define consumerNum  5
#define sleepTime 2000

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;
//生产者
void * producer(void * a){
    while(true){
        while(mutex <= 0);//缓冲区位置不够,一直循环等待,S<=0不断【检测测试】
        mutex--;//实现互斥的P操作【上锁】,缓冲区位置足够,占用一个位置资源
        
        proCount++;//生产一个产品
        printf("生产一个产品ID%d, 缓冲区位置为%d\n",proCount,in);

        while(empty <= 0){
            printf("缓冲区已满!\n");
        }
        empty--;//实现同步的P操作

        buffer[in] = proCount;
        in = (in + 1) % N;    
        
        mutex++;//实现互斥的V操作【开锁】
        full++;//实现同步的V操作
        Sleep(sleepTime);
    }
}
//消费者
void * consumer(void *b){
    while(true){
        while(full <= 0){
            printf("缓冲区为空!\n");
        }
        full--;//实现同步的P操作

        while(mutex <= 0);
        mutex--;//实现互斥的P操作【上锁】

        int nextc = buffer[out];
        buffer[out] = 0;//消费完将缓冲区设置为0

        out = (out + 1) % N;

        mutex++;//实现互斥的V操作【开锁】
        empty++;//实现同步的V操作

        printf("\t\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;//创建一个生产者线程
        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("ERROR: fail to recollect\n");
            exit(1);
        }
    }//运行线程池
    return 0;
}

运行结果部分截图如下:
1

1.1.2 Unix环境

1、代码如下

#include <stdio.h>
#include <pthread.h>//线程的创建
#define N 100
#define true 1
#define producerNum  10
#define consumerNum  5

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;
//生产者
void * producer(void * a){
    while(true){
        while(mutex <= 0);//缓冲区位置不够,一直循环等待,S<=0不断【检测测试】
        mutex--;//实现互斥的P操作【上锁】,缓冲区位置足够,占用一个位置资源
        
        proCount++;//生产一个产品
        printf("生产一个产品ID%d, 缓冲区位置为%d\n",proCount,in);

        while(empty <= 0){
            printf("缓冲区已满!\n");
        }
        empty--;//实现同步的P操作

        buffer[in] = proCount;
        in = (in + 1) % N;     
       
        mutex++;//实现互斥的V操作【开锁】
        full++;//实现同步的V操作
    }
}
//生产者
void * producer(void * a){
    while(true){
        while(mutex <= 0);//缓冲区位置不够,一直循环等待,S<=0不断【检测测试】
        mutex--;//实现互斥的P操作【上锁】,缓冲区位置足够,占用一个位置资源
        
        proCount++;//生产一个产品
        printf("生产一个产品ID%d, 缓冲区位置为%d\n",proCount,in);

        while(empty <= 0){
            printf("缓冲区已满!\n");
        }
        empty--;//实现同步的P操作

        buffer[in] = proCount;
        in = (in + 1) % N;    
        
        mutex++;//实现互斥的V操作【开锁】
        full++;//实现同步的V操作
        Sleep(sleepTime);
    }
}
//消费者
void * consumer(void *b){
    while(true){
        while(full <= 0){
            printf("缓冲区为空!\n");
        }
        full--;//实现同步的P操作

        while(mutex <= 0);
        mutex--;//实现互斥的P操作【上锁】

        int nextc = buffer[out];
        buffer[out] = 0;//消费完将缓冲区设置为0

        out = (out + 1) % N;

        mutex++;//实现互斥的V操作【开锁】
        empty++;//实现同步的V操作

        printf("\t\t\t\t\t消费一个产品ID%d,缓冲区位置为%d\n", nextc,out);
    }
}
//主函数
int main()
{
    pthread_t threadPool[producerNum+consumerNum];//创建线程池
    int i;
    for(i = 0; i < producerNum; i++){
        pthread_t temp;//创建一个生产者线程
        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("ERROR: fail to recollect\n");
            exit(1);
        }
    }//运行线程池
    return 0;
}

2、编译运行

错误编译:

~$ gcc -o fileName fileName.c

2

正确编译:

/*
注意:该程序为多线程程序
1、需要添加头文件#inlcude <pthread.h>才能创建线程
2、编译时需要手动连接pthread库
	因为pthread不是Linux系统的默认库,而是POSIX线程库。连接时需要使用库libpthread.a。在代码中使用pthread_create、pthrea_join等时,在编译中要加-lpthread参数。在Linux中将其作为一个库来使用,因此加上 -lpthread(或-pthread)以显式链接该库。
*/
~$ gcc fileName.c -lpthread -o fileName //编译
~$ ./fileName //运行

运行结果部分截图如下:
在这里插入图片描述

1.2 记录型信号量

1、代码如下

#include <stdio.h>
#include <windows.h>
#include <unistd.h>
#define N 100
#define true 1
#define producerNum  10
#define consumerNum  5
#define sleepTime 2000

typedef struct{
	int value;
	struct process_control_block *list;
}semaphore;

void wait(semaphore *S){
	S->value--;
	if(S->value<0)block(S->list);
}

void signal(semaphore *S){
	S->value++;
	if(S->value<=0)wakeup(S->list);
}

typedef int item;
item buffer[N] = {0};
int in = 0;
int out = 0;
int proCount = 0;
semaphore *mutex,*empty,*full;

 
void* producer(){
	int i = 0;
	do{
		wait(empty);
		wait(mutex);
		
		proCount++;
		printf("生产一个产品ID%d,缓冲区位置为%d\n",proCount,in);
		while(empty->value<=0){
			printf("缓冲区已满!\n");
		}
		buffer[in] = proCount;
		in = (in+1) % N;
		
		signal(mutex);
		signal(full);
	    Sleep(sleepTime);
	}while(i<100);
}
 
void* consumer(){
	int i=0;
	do{
		while(full->value <= 0){
            printf("缓冲区为空!\n");
        }
		wait(full);
		wait(mutex);
		
		int nextc = buffer[out];
		out = (out+1) % N;
		
		signal(mutex);
		signal(empty); 
		
		printf("\t\t\t\t\t消费一个产品ID%d,缓冲区位置为%d\n", nextc,out);
		Sleep(sleepTime);
	}while(i<15);
	return NULL;
}
int main(){
	mutex->value = 1;
	empty->value = N;
	full->value = 0;
	producer();
	consumer();
	return 0;
}

问题:block和wakeup未实现


——by一宇 2020-01-04
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_45011621/article/details/112208338

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值