【操作系统】多线程、生产者——消费者同步与互斥代码实现
简述:
两进程同步关系,有两个信号量,一个empty一个full。
假设产品缓冲区大小为n,则初值empty=n,full=0。
前操作(生产者):
P(empty)
V(full)
后操作(消费者):
P(full)
P(empty)
如果需要互斥访问缓冲区的话,要保证临界区代码尽量小,且需要避免死锁。
前操作(生产者):
P(empty)
P(mutex)
V(mutex)
V(full)
后操作(消费者):
P(full)
P(mutex)
V(mutex)
P(empty)
代码实现:
#include <stdio.h>
#include <windows.h>/* 互斥与同步 */#define N 10 // 缓存区大小
#define COUNT 10 // 模拟次数权重(=总执行次数/生产者线程数/消费者线程数/2)
#define P_TIME 100 // 生产一个产品时间
#define C_TIME 50 // 消耗一个产品时间
#define P_COUNT 5 // 生产者线程数量
#define C_COUNT 3 // 消费者线程数量HANDLE mutex = CreateMutex(NULL, FALSE, NULL); // 定义互斥量
HANDLE empty = CreateSemaphore(NULL, N, N, NULL); // 缓冲区中空槽数信号量
HANDLE full = CreateSemaphore(NULL, 0, N, NULL); // 缓冲区中满槽数信号量int buffer[N]; // 有N个槽数的缓冲区buffer[N],并实现循环缓冲队列
int front = 0; // 定义头指针
int rear = 0; // 定义尾指针DWORD WINAPI producer(LPVOID lpParameter); // 生产者线程函数
DWORD WINAPI consumer(LPVOID lpParameter); // 消费者线程函数void myPrint(); // 输出缓冲区示意数组int main()
{HANDLE p_thread[P_COUNT]; // 生产者线程数组HANDLE c_thread[C_COUNT]; // 消费者线程数组HANDLE handle[P_COUNT + C_COUNT]; // 线程数组for (int i = 0; i < P_COUNT; i++){do{p_thread[i] = CreateThread(NULL, 0, producer, NULL, 0, NULL); // 创建生产者线程} while (!p_thread[i]); // 创建失败则重新创建handle[i] = p_thread[i]; // 将生产者线程放置线程数组中}for (int i = 0; i < C_COUNT; i++){do{c_thread[i] = CreateThread(NULL, 0, consumer, NULL, 0, NULL); // 创建消费者线程} while (!c_thread[i]); // 创建失败则重新创建handle[P_COUNT + i] = c_thread[i]; // 将消费者线程放置线程数组中}WaitForMultipleObjects(P_COUNT + C_COUNT, handle, TRUE, INFINITE); // 等待线程运行完毕return 0;
}/* 生产者线程函数 */
DWORD WINAPI producer(LPVOID lpParameter)
{int i = 0;while (i < COUNT * C_COUNT){WaitForSingleObject(empty, INFINITE); // 如果该槽没有产品=>P(empty)WaitForSingleObject(mutex, INFINITE); // 进入临界区,访问缓冲区临界资源=>P(mutex)buffer[front] = 1; // 生产产品front = (front + 1) % N; // 指针移动i++;Sleep(P_TIME); // 产品生产时间printf("生产产品\n");myPrint(); // 打印演示ReleaseMutex(mutex); // 退出临界区=>V(mutex)ReleaseSemaphore(full, 1, NULL); // 满槽记录=>V(full)}return 0;
}/* 消费者线程函数 */
DWORD WINAPI consumer(LPVOID lpParameter)
{int i = 0;while (i < COUNT * P_COUNT){WaitForSingleObject(full, INFINITE); // 如果该槽存在产品=>P(full)WaitForSingleObject(mutex, INFINITE); // 进入临界区,访问缓冲区临界资源=>P(mutex)buffer[rear] = 0; // 消耗产品rear = (rear + 1) % N; // 指针移动i++;Sleep(C_TIME); // 产品消耗时间printf("消费产品\n");myPrint(); // 打印演示ReleaseMutex(mutex); // 退出临界区=>V(mutex)ReleaseSemaphore(empty, 1, NULL); // 空槽记录=>V(empty)}return 0;
}/* 输出缓冲区示意数组 */
void myPrint()
{printf("缓冲区示意数组:");for (int i = 0; i < N; i++){printf("%d ", buffer[i]); // 打印缓冲区数组}printf("\n");
}
运行截图:
【操作系统】多线程、生产者——消费者同步与互斥代码实现相关推荐
- 操作系统课设--使用信号量解决生产者/消费者同步问题
山东大学操作系统课设lab3 实验三 使用信号量解决生产者/消费者同步问题(lab3) 实验目的 理解Nachos的信号量是如何实现的 生产者/消费者问题是如何用信号量实现的 在Nachos中是如何创 ...
- python多线程实现生产者消费者_用Python实现多线程“生产者-消费者”模型的简单例子...
用 Python 实现多线程"生产者 - 消费者"模型的简单例子 生产者消费者问题是一个著名的线程同步问题, 该问题描述如下: 有一个生产者在生产产品, 这些产品将提供给若干个消费 ...
- linux多线程 消费者,linux c 多线程 生产者-消费者二
linux c 多线程 生产者--消费者2 实在不好意思,第一个版本有些问题,是局部变量和堆里面变量的区别.今天做了一下修改.代码如下. #ifndef _LIST_H_ #define _LIST_ ...
- Java基础_17 | Java多线程程序设计(Java中两种创建线程的方法、多线程之间的同步和互斥)
1. 多线程实现最核心的机制 一个程序在其执行过程中, 可以产生多个线程, 形成多条执行线索.,每条线程,有产生.存在和消亡的过程,并且独立完成各自的功能,互不干扰. 多线程程序运行只占用一个CPU, ...
- Java多线程-生产者消费者问题(多个消费者多个生产者)
Java多线程-生产者消费者问题(多个消费者多个生产者) public class ConsumerProcuderDemo {public static void main(String[] arg ...
- Python多线程篇一,theanding库、queue队列、生产者消费者模式爬虫实战代码超详细的注释、自动分配线程对应多任务,GIF演示【傻瓜式教程】
⭐ 简介:大家好,我是zy阿二,我是一名对知识充满渴望的自由职业者. ☘️ 最近我沉溺于Python的学习中.你所看到的是我的学习笔记. ❤️ 如果对你有帮助,请关注我,让我们共同进步.有不足之处请留 ...
- 【操作系统】生产者消费者问题
生产者消费者模型 文章目录 生产者消费者模型 @[toc] 一. 生产者消费者问题 二. 问题分析 三. 伪代码实现 四.代码实现(C++) 五. 互斥锁与条件变量的使用比较 一. 生产者消费者问题 ...
- 操作系统实验 生产者消费者问题详解
操作系统课程设计 生产者消费者实验报告 一.实验目的 加深对进程概念的理解,明确进程与程序的区别. 认识并发执行的本质. 理解和掌握Linux和Windows进程通信系统调用的功能,通过实验和学习,提 ...
- Linux多线程——生产者消费者模型
目录 一.生产者消费者模型 1.1 什么是生成者消费者模型 1.2 生产者消费者模型的优点 1.3 基于阻塞队列实现生产者消费者模型 1.4 POSIX信号量 1.4.1 信号量概念 1.4.2 P操 ...
最新文章
- 国内第一部IT治理综合图书问世
- 基于C++有限状态机的实现技术
- 线性代数:二次型为什么可以用矩阵表示?——分组因式分解推导
- R语言与正态总体均值的区间估计
- Eclipse里代码自动完成 auto completion的快捷键设置
- jzoj1265-Round Numbers【数位统计】
- 不能启动u盘 uefi_不知道怎么进入主板设置U盘启动,试试这些方式
- 在Entity Framework中使用事务
- U811.1接口EAI系列之三--采购订单生成--VB语言
- asp.net MVC初学体会.
- 【STM32】WS2812B灯珠的PWM+DMA控制(库函数)
- VBA学习之一:基本知识
- LayaBox微信小游戏截图功能 利用微信API实现完美截图
- 计算机丢失iggy,我似乎已经丢失了什么
- 计算年龄:sql计算
- codeforces 884B Japanese Crosswords Strike Back
- Python网络编程之初识
- linux debian教程,Debian安装全攻略
- 【Leetcode】1641. Count Sorted Vowel Strings
- 51单片机控制SG90舵机、MG90S舵机