信号量实现生产者消费者程序_C语言示例

信号量的基本思想是通过一个计数器和一组相关的操作来实现资源的控制和同步。计数器表示可用的资源数量,每次访问共享资源时,线程需要先申请信号量,如果信号量的计数器大于零,则线程可以访问共享资源并将计数器减一;如果计数器为零,则线程需要等待,直到其他线程释放资源,使计数器变为非零。
信号量和线程锁Mutex有很多相似之处,也有些不同点:
①Mutex只能是0和1,0表示上锁,1表示释放锁。但是semaphore可以大于1。
②信号量可以用于线程间,也可以用于进程间通信。但是Mutex只能用于线程间通信。
主要有以下几个函数:

int sem_init (sem_t *sem, int pshared, unsigned int value);//初始化信号量
int sem_wait(sem_t *sem); //阻塞等,等不到就一直阻塞着等
int sem_trywait(sem_t *sem); //非阻塞等
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); //定时等

生产者消费者模型如下:
创建个仓库,里面有5个空位,可以放0-5件商品。
如果放满了没人来取商品,就是爆仓
如果取货时没货,就是崩盘

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#define _POSIX_C_SOURCE 200809L
#include <semaphore.h>#define NUM 5int q[NUM];//仓库,最多能放5件物品sem_t* blank_number;
sem_t* goods_number;void* producer(void* arg)
{int i = 0;while(1){sem_wait(blank_number);//抢空位,抢不到就一直等q[i] = rand() % 100 + 1;printf("produce %d\n", q[i]);sem_post(goods_number); //增加一个商品i = (i + 1) % NUM;sleep(rand()%3); //每次休息1-3秒钟}
}void* consumer(void *arg)
{int i = 0;while(1){sem_wait(goods_number);//抢商品,抢不到就阻塞printf("consume %d\n", q[i]);q[i] = 0; //消费掉这个商品sem_post(blank_number);//释放一个空位i = (i + 1) % NUM;sleep(rand() % 3); //每次休息1-3秒钟}
}int main()
{
//使用time(NULL)函数返回的当前时间作为种子,然后传递给srand函数,以初始化伪随机数生成器。
//通常情况下,如果不给伪随机数生成器提供一个种子,那么每次程序运行时生成的随机数都是相同的。srand(time(NULL));//下面2行是Linux的写法// sem_init(blank_number, 0, NUM); //空位,0表示单进程多线程,一开始5个空位// sem_init(blank_number, 0, 0); //产品,0表示单进程多线程,一开始0个商品//下面2行是mac的写法blank_number = sem_open("blank_number", O_CREAT, S_IRUSR | S_IWUSR, NUM);goods_number = sem_open("goods_number", O_CREAT, S_IRUSR | S_IWUSR, 0);pthread_t pid, cid;//生产者ID和消费者IDpthread_create(&pid, NULL, producer, NULL); //起生产者线程pthread_create(&cid, NULL, consumer, NULL); //起消费者线程pthread_join(pid, NULL);pthread_join(cid, NULL);return 0;
}

结果是:

zhanghaodeMacBook-Pro:cpp_excise zhanghao$ ./a.out 
produce 96
produce 85
consume 96
consume 43
consume 18
produce 4
produce 56
produce 64
produce 81
^C

注:这个代码,可以检测到崩盘:消费如果为0,说明当前没货,就崩盘了。但爆仓检测不到。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/761870.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Handler使用介绍

Android 中的 Handler 是用来和线程通信的重要工具。它主要用于在后台线程中执行任务&#xff0c;并将结果传递回主线程以更新用户界面。 一、基本概念 线程间通信&#xff1a; Android 应用通常具有主线程&#xff08;也称为 UI 线程&#xff09;和后台线程。Handler 允许您从…

操作系统面经-程序和进程的区别

1.程序、进程、线程简述 程序的基本概念 程序是含有指令和数据的文件&#xff0c;被存储在磁盘或其他的数据存储设备中&#xff0c;也就是说程序是静态的代码。 进程的基本概念 在多道程序环境下&#xff0c;允许多个程序并发执行&#xff0c;此时它们将失去封闭性&#xf…

Verilog刷题笔记41

题目&#xff1a;Create 8 D flip-flops with active high asynchronous reset. All DFFs should be triggered by the positive edge of clk. 解题&#xff1a; module top_module (input clk,input areset, // active high asynchronous resetinput [7:0] d,output [7:0]…

ollama -linux部署

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 安装对应的包启动ollama启动llama2大模型&#xff08;新开一个终端&#xff09;python接口对话streamlit对话 安装对应的包 # linux 安装curl -fsSL https://ollam…

开发chrome扩展( 禁止指定域名使用插件)

mainfest.json: {"manifest_version": 3,"name": "ChatGPT学习","version": "0.0.2","description": "ChatGPT,GPT-4,Claude3,Midjourney,Stable Diffusion,AI,人工智能,AI","icons": {&quo…

哪些事是你当了领导才明白的?

哪些事是你当了领导才明白的&#xff1f; 毕业5年&#xff0c;17年开始带团队&#xff0c;确实很多事不做到管理这一层&#xff0c;就真的意识不到。 带着【执行者】和【管理者】这2个视角&#xff0c;再结合我毕业至今这5年的所有职场经历&#xff0c;聊聊“职场潜规则”。 …

docker swarm 集群创建

1&#xff0c;目的&#xff1a; 通过docker swarm 工具将一台或者多台安装了docker的服务器组成一个完整的集群&#xff0c;该集群中的node节点可以通过Leader节点管理。在使用docker stack部署时&#xff0c;可以将容器自动分发到合适的节点上。 2&#xff0c;服务器准备&am…

python统计分析——t分布、卡方分布、F分布

参考资料&#xff1a;python统计分析【托马斯】 一些常见的连续型分布和正态分布分布关系紧密。 t分布&#xff1a;正态分布的总体中&#xff0c;样本均值的分布。通常用于小样本数且真实的均值/标准差不知道的情况。 卡方分布&#xff1a;用于描述正态分布数据的变异程度。 F分…

R语言Meta分析核心技术:科研论文写作与数据可视化技巧

R语言作为一种强大的统计分析和绘图语言&#xff0c;在科研领域发挥着日益重要的作用。其中&#xff0c;Meta分析作为一种整合多个独立研究结果的统计方法&#xff0c;在R语言中得到了广泛的应用。通过R语言进行Meta分析&#xff0c;研究者能够更为准确、全面地评估某一研究问题…

ShardingSphere+JPA+Druid实现分表操作

要在SpringBoot项目中实现分表操作&#xff0c;本文使用的是ShardingSphereJPADruid实现。过程中出现问题记录一下。 准备MySQL数据库表 这里准备的是一张主表test_cost&#xff0c;两张从表test_cost_0和test_cost_1&#xff0c;结构需要相同&#xff0c;主表只是声明了表结构…

嵌入式学习-ARM

嵌入式学习-ARM STM32串口控制三盏灯亮灭 MAIN.C #include "uart4.h" int main() {uart4_init();gpio_init();char str[32];while (1){gets(str);if (my_strcmp(str,"A") 0){led1();}else if (my_strcmp(str,"B") 0){led2();}else if (my_s…

用大语言模型控制交通信号灯,有效缓解拥堵!

城市交通拥堵是一个全球性的问题&#xff0c;在众多缓解交通拥堵的策略中&#xff0c;提高路口交通信号控制的效率至关重要。传统的基于规则的交通信号控制&#xff08;TSC&#xff09;方法&#xff0c;由于其静态的、基于规则的算法&#xff0c;无法完全适应城市交通不断变化的…

Tabulator-tables5.6版本升级6.0版本

npm install tabulator-table 报错内容 /node_modules/tabulator-tables/dist/js/tabulator_esm.js 658:19 Module parse failed: Unexpected token (658:19) You may need an appropriate loader to handle this file type, currently no loaders are configured to process…

Tensorflow2.0笔记 - 链式法则例子

本笔记简单记录链式法则的原理&#xff0c;关于链式法则&#xff0c;本身和高等数学中的链式求导法则是一样的&#xff0c;深度学习中相关资料可以参考这里&#xff1a; 【深度学习之美22】BP算法详解之链式法则 - 知乎10.5 什么是计算图&#xff1f;我们知道&#xff0c; 神经…

Windows环境下编译ffmpeg 6.1源码--Virtual Studio + Msys2方式

环境准备 约定&#xff1a;源码全部放到sources下&#xff0c;目录结构说明 /d/java/ffmpeg #工程工目录 ├── build #存放编译文件的目录&#xff0c;子目录为具体模块的构建目录 │ ├── fdk-aac │ ├── ffmpeg │ └── x264 ├── instal…

机器学习流程—AutoML

文章目录 机器学习流程—AutoMLAutoML工具Auto-SKLearnMLBoxTPOTRapidMinerPyCaretAuto-KerasH2OAutoML谷歌AutoML云Uber LudwigTransmogrifAIAutoGluonAutoWekaDataRobot

稀碎从零算法笔记Day24-LeetCode:存在重复元素

前言&#xff1a;本打算练习下机写快排&#xff0c;但是快排超时了(为什么sort没超时啊。。) 题型&#xff1a;排序、哈希表 链接&#xff1a;存在重复元素 - 提交记录 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 题目样例 题目思路 C代…

提升水库大坝安全与效率:现代技术云平台的应用

在我国&#xff0c;水库大坝的数量居世界之首&#xff0c;它们在推动国民经济发展中扮演着不可或缺的角色。然而&#xff0c;要想让这些水利工程充分发挥其价值&#xff0c;不仅需要精准的调度与高效的管理&#xff0c;更重要的是要确保其安全无虞。一旦发生事故&#xff0c;后…

linux 使用 go 连接 etcd 集群时报错

问题分析 在 ubuntu 中使用 github.com/coreos/etcd/clientv3 第三方库报错&#xff0c;报错信息如下&#xff1a; # github.com/coreos/etcd/clientv3/balancer/resolver/endpoint /root/go/pkg/mod/github.com/coreos/etcdv3.3.27incompatible/clientv3/balancer/resolver/…

鸿蒙Harmony应用开发—ArkTS-全局UI方法(列表选择弹窗)

列表弹窗。 说明&#xff1a; 从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 本模块功能依赖UI的执行上下文&#xff0c;不可在UI上下文不明确的地方使用&#xff0c;参见UIContext说明。 从API version 10开始&#xff0…