简述:

两进程同步关系,有两个信号量,一个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");
}

运行截图:

【操作系统】多线程、生产者——消费者同步与互斥代码实现相关推荐

  1. 操作系统课设--使用信号量解决生产者/消费者同步问题

    山东大学操作系统课设lab3 实验三 使用信号量解决生产者/消费者同步问题(lab3) 实验目的 理解Nachos的信号量是如何实现的 生产者/消费者问题是如何用信号量实现的 在Nachos中是如何创 ...

  2. python多线程实现生产者消费者_用Python实现多线程“生产者-消费者”模型的简单例子...

    用 Python 实现多线程"生产者 - 消费者"模型的简单例子 生产者消费者问题是一个著名的线程同步问题, 该问题描述如下: 有一个生产者在生产产品, 这些产品将提供给若干个消费 ...

  3. linux多线程 消费者,linux c 多线程 生产者-消费者二

    linux c 多线程 生产者--消费者2 实在不好意思,第一个版本有些问题,是局部变量和堆里面变量的区别.今天做了一下修改.代码如下. #ifndef _LIST_H_ #define _LIST_ ...

  4. Java基础_17 | Java多线程程序设计(Java中两种创建线程的方法、多线程之间的同步和互斥)

    1. 多线程实现最核心的机制 一个程序在其执行过程中, 可以产生多个线程, 形成多条执行线索.,每条线程,有产生.存在和消亡的过程,并且独立完成各自的功能,互不干扰. 多线程程序运行只占用一个CPU, ...

  5. Java多线程-生产者消费者问题(多个消费者多个生产者)

    Java多线程-生产者消费者问题(多个消费者多个生产者) public class ConsumerProcuderDemo {public static void main(String[] arg ...

  6. Python多线程篇一,theanding库、queue队列、生产者消费者模式爬虫实战代码超详细的注释、自动分配线程对应多任务,GIF演示【傻瓜式教程】

    ⭐ 简介:大家好,我是zy阿二,我是一名对知识充满渴望的自由职业者. ☘️ 最近我沉溺于Python的学习中.你所看到的是我的学习笔记. ❤️ 如果对你有帮助,请关注我,让我们共同进步.有不足之处请留 ...

  7. 【操作系统】生产者消费者问题

    生产者消费者模型 文章目录 生产者消费者模型 @[toc] 一. 生产者消费者问题 二. 问题分析 三. 伪代码实现 四.代码实现(C++) 五. 互斥锁与条件变量的使用比较 一. 生产者消费者问题 ...

  8. 操作系统实验 生产者消费者问题详解

    操作系统课程设计 生产者消费者实验报告 一.实验目的 加深对进程概念的理解,明确进程与程序的区别. 认识并发执行的本质. 理解和掌握Linux和Windows进程通信系统调用的功能,通过实验和学习,提 ...

  9. Linux多线程——生产者消费者模型

    目录 一.生产者消费者模型 1.1 什么是生成者消费者模型 1.2 生产者消费者模型的优点 1.3 基于阻塞队列实现生产者消费者模型 1.4 POSIX信号量 1.4.1 信号量概念 1.4.2 P操 ...

最新文章

  1. 国内第一部IT治理综合图书问世
  2. 基于C++有限状态机的实现技术
  3. 线性代数:二次型为什么可以用矩阵表示?——分组因式分解推导
  4. R语言与正态总体均值的区间估计
  5. Eclipse里代码自动完成 auto completion的快捷键设置
  6. jzoj1265-Round Numbers【数位统计】
  7. 不能启动u盘 uefi_不知道怎么进入主板设置U盘启动,试试这些方式
  8. 在Entity Framework中使用事务
  9. U811.1接口EAI系列之三--采购订单生成--VB语言
  10. asp.net MVC初学体会.
  11. 【STM32】WS2812B灯珠的PWM+DMA控制(库函数)
  12. VBA学习之一:基本知识
  13. LayaBox微信小游戏截图功能 利用微信API实现完美截图
  14. 计算机丢失iggy,我似乎已经丢失了什么
  15. 计算年龄:sql计算
  16. codeforces 884B Japanese Crosswords Strike Back
  17. Python网络编程之初识
  18. linux debian教程,Debian安装全攻略
  19. 【Leetcode】1641. Count Sorted Vowel Strings
  20. 51单片机控制SG90舵机、MG90S舵机

热门文章

  1. Matlab之绘制三维曲面图
  2. 绿芯GreenChip电容式触控触摸IC型号性能介绍
  3. tensor多维向量的简单理解
  4. Python numpy函数:reshape()
  5. mysql 、pg 查询日期处理
  6. 思考者的回归--转帖今何在的优美文章《窗》之三
  7. 湖州云计算机,湖州云存储服务_菲尔云计算
  8. python证书考试报名时间,python证书考试报名条件
  9. 生成式语言大模型压缩技术思考——以ChatGPT为例
  10. EF系列(二)——DbContext 和DbSet