linux系统编程:线程同步-信号量(semaphore)

2023-11-02

                             线程同步-信号量(semaphore)

生产者与消费者问题再思考

在实际生活中,只要有商品,消费者就可以消费,这没问题。但生产者的生产并不是无限的,例如,仓库是有限的,原材料是有限的,生产指标受消费指标限制等等。为了进一步,解决好生产者与消费者问题,引入信号量进机制。


信号量

信号量(semaphore)是互斥量的升级版:互斥量的状态为0或1,而信号量可以为n。也就是说,使用互斥量时,最多允许一个线程进入关键区,而信号量允许多个,具体值是信号量当前的内部值。


相关函数

sem_t       //信号量类型
sem_init(sem_t *sem, int pshared, unsigned int value);
sem_wait(sem_t *sem)
sem_trywait
sem_timedwait
sem_post(sem_t *sem)
sem_destroy
重要的是理解:sem_wait和sem_post两个函数。

sem_wait(sem);当sem为零时,线程阻塞;否则,sem减一,线程不阻塞。

sem_post(sem);sem加一。

此外,使用sem_init方法,对信号量类型初始化,第二个参数,默认是0,标明用于线程之间。第三个参数指定了初始值。


单生产者与单消费者

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM 5
sem_t blank_num, product_num;
int i, j, k;
int goods[NUM];
void *producer(void *argv)
{
	while (1)
	{
		sem_wait(&blank_num);
		goods[i] = rand() % 100 + 1;
		printf("produce %d\n", goods[i]);
		sem_post(&product_num);
		i = (i + 1) % NUM;
		sleep(rand() % 2);
	}
}
void *comsumer(void *argv)
{
	while (1)
	{
		sem_wait(&product_num);
		printf("comsume %d\n", goods[j]);
		goods[j] = 0;
		sem_post(&blank_num);
		j = (j + 1) % NUM;
		sleep(rand() % 2);
	}
}
int main(void)
{
	i = j = k = 0;
	//初始化信号量
	sem_init(&blank_num, 0, NUM);
	sem_init(&product_num, 0, 0);
	pthread_t pro, com;
	pthread_create(&com, NULL, producer, NULL);
	pthread_create(&pro, NULL, comsumer, NULL);
	pthread_join(com, NULL);
	pthread_join(pro, NULL);
	sem_destroy(&blank_num);
	sem_destroy(&product_num);
	return 0;
}


多生产者与多消费者

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM 5
pthread_mutex_t m1, m2;
sem_t blank_num, product_num;
int goods[NUM];
int i, j, k;
void *producer(void *argv)
{
	while (1)
	{
		sem_wait(&blank_num);
		pthread_mutex_lock(&m1);
		goods[i] = rand() % 100 + 1;
		printf("produce %d\n", goods[i]);
		i = (i + 1) % NUM;
		pthread_mutex_unlock(&m1);
		sem_post(&product_num);
		sleep(rand() % 2);
	}
}
void *comsumer(void *argv)
{
	while (1)
	{
		sem_wait(&product_num);
		pthread_mutex_lock(&m2);
		printf("comsume %d\n", goods[j]);
		goods[j] = 0;   //置零
		j = (j + 1) % NUM;
		pthread_mutex_unlock(&m2);
		sem_post(&blank_num);
		sleep(rand() % 2);
	}
}
int main(void)
{
	i = j = k = 0;
	//初始化信号量及互斥量
	sem_init(&blank_num, 0, NUM);
	sem_init(&product_num, 0, 0);
	pthread_mutex_init(&m1, NULL);
	pthread_mutex_init(&m2, NULL);
	pthread_t pro[2], com[3];
	for (k = 0; k < 3; k++)
		pthread_create(&com[k], NULL, producer, NULL);
	for (k = 0; k < 2; k++)
		pthread_create(&pro[k], NULL, comsumer, NULL);
	for (k = 0; k < 3; k++)
		pthread_join(com[k], NULL);
	for (k = 0; k < 2; k++)
		pthread_join(pro[k], NULL);
	pthread_mutex_destroy(&m1);
	pthread_mutex_destroy(&m2);
	sem_destroy(&blank_num);
	sem_destroy(&product_num);
	return 0;
}


     

CCPP Blog 目录


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux系统编程:线程同步-信号量(semaphore) 的相关文章

  • 主线程退出后,子线程会不会退出

    额 好吧 这是个标题党 其实所有的线程都是平级的 根本不存在主线程和子线程 下文所述为了方便 将在main函数中的线程看做主线程 其它线程看成子线程 特此说明 先考虑以下代码 include
  • Linux中select poll和epoll的区别

    select的本质是采用32个整数的32位 即32 32 1024来标识 fd值为1 1024 当fd的值超过1024限制时 就必须修改FD SETSIZE的大小 这个时候就可以标识32 max值范围的fd 对于单进程多线程 每个线程处理多
  • 【Linux】进程优先级,环境变量,进程地址空间

    文章目录 1 进程优先级 基本概念 查看系统进程 PRI and NI PRI vs NI 修改进程优先级的命令 其他概念 2 环境变量 基本概念 查看环境变量方法 常见环境变量 测试PATH 环境变量相关的命令 环境变量的组织方式 通过代
  • MATLAB 中的信号量和锁

    我正在开发一个 MATLAB 项目 希望有两个 MATLAB 实例并行运行并共享数据 我将调用这些实例MAT 1 and MAT 2 更具体地说 该系统的架构是 MAT 1按顺序处理图像 使用以下命令一一读取它们imread 并使用输出每个
  • Ada 中的信号量

    我得到了以下代码并要求实现一个信号量 with Ada Text IO use Ada Text IO with Id Dispenser with Semaphores use Semaphores procedure Philos is
  • 信号量会阻止指令重新排序吗?

    我一直在寻找 C 中锁定语句的可等待等效项 有些人建议使用二进制文件SemaphoreSlim通过以下方式 await semaphore WaitAsync ConfigureAwait false try inner instructi
  • 信号量和条件的区别(ReentrantLock)

    有谁知道这些方法之间的区别acquire and release java util concurrent Semaphore and await and signal new ReentrantLock newCondition 您能为每
  • CountDownLatch 与信号量

    使用有什么好处吗 java util concurrent CountdownLatch 代替 java util concurrent Semaphore 据我所知 以下片段几乎是等效的 1 信号量 final Semaphore sem
  • 具有优先级的信号量

    我知道关于Semaphore类中的System Threading命名空间 但我不知道它是否允许等待线程具有不同的优先级 如果两个线程正在等待一个空位 有没有办法让优先级较高的线程拥有第一个空位 来自MSDN 文档 http msdn mi
  • 在.NET 4中使用await SemaphoreSlim.WaitAsync

    我的应用程序正在使用 NET 4 我正在使用等待异步努吉特包 https www nuget org packages Microsoft Bcl Async 在我的应用程序中 我想对信号量 WaitAsync 调用进行等待 如下所示 Se
  • 跨进程(和机器)同步(信号量)

    背景 我的 WCF 应用程序必须调用一个没有任何并发 检查的服务 它是由第三方创建的服务 让他们添加并发检查可能是不可能的 我可以确保调用第三方服务的唯一方法是通过我的 WCF 应用程序 所以我正在考虑在我的代码中添加并发检查 为此 我将使
  • 寻找监视器与信号量的良好类比/示例

    监视器应该解决并发环境中的信号量问题 我正在寻找使用监视器与信号量的良好类比 请使用信息进行类比 4 个任务 任务S 任务 任务 任务S 1 个变量 varX 每个任务都想根据某个事件来操作varX 假设一群病人想要去看医生 信号量的实现是
  • 为什么 sem_open 与 fork() 一起使用而不使用共享内存?

    即使信号量不在共享内存中 该程序也可以工作 我测试过 请注意我如何在 fork 之前创建一次变量 另一方面 用创建的信号量sem init 需要在共享内存中才能工作 但这仍然是一个sem t结构 那么为什么它不需要共享内存呢 的内容是sem
  • 用餐哲学家挨饿的可能性

    我需要检查解决哲学家就餐问题的算法是否保证满足以下所有条件 不存在僵局的可能性 没有挨饿的可能 我正在使用信号 http en wikipedia org wiki Semaphore 28programming 29放在筷子上即可解决问题
  • 具有 beginwait 函数的信号量

    我正在使用 begin end 编写一个异步库 并且需要锁定对象 目前 我正在使用信号量执行此操作 但调用semaphore WaitOne 在调用该线程的地方挂起该线程 我宁愿使用像 BeginWait 这样的东西 这样它会立即返回并在信
  • 使用易失性变量和信号量 - Java

    我从线程 信号量 易失变量等开始 我想知道当我使用信号量时是否有必要将变量定义为易失性 我的意思是 有 2 个线程 一个增加变量 另一个减少变量 例如 显然 在每次访问之前 我有一个互斥体 它随时控制只有一个线程正在 玩 变量 有必要定义为
  • 命名和未命名的 posix 信号量

    计划使用 posix 信号量来同步 2 个进程 不太确定使用哪个 命名或未命名 各自的优点和缺点是什么 我如何决定使用哪个 在哪些情况下 其中一种优于另一种 Thanks 如果两个进程不相关 您应该使用命名信号量 如果两个进程相关 即分叉
  • 父进程和子进程如何进行信号量操作?

    semget 调用是否在父进程和子进程之间共享信号量 我有这段代码 对于相同的代码 我观察到如果父进程首先运行 子进程有时会获得更改后的信号量值 但是当子进程首先运行时 父进程似乎永远不会携带更改后的信号量 为什么会发生这种情况 谁能向我解
  • shell脚本中是否有互斥/信号量机制?

    我正在 shell 脚本中寻找互斥 信号量 并发机制 考虑以下情况 除非 a 用户不关闭共享文件 否则 b 用户应该无法打开 更新它 我只是想知道如何在 shell 脚本中实现互斥量 信号量 临界区等 在 shell 脚本中实现锁定机制 文
  • .Net Core 异步关键部分(如果在同一实体上工作)

    我需要确保通过 Web API 访问的方法不能同时通过多个调用访问 如果它在具有相同 id 的同一对象上工作 我理解使用SemaphoreSlim但一个简单的实现将锁定所有人的关键部分 但只有当该部分适用于同一实体而不是两个不同的实体时 我

随机推荐

  • antd中Form.Item无法获取到对应的表单值解决

    antd中Form Item无法获取到对应的表单值解决 前言 问题代码示例 解决 前言 本文章讲的解决方案只是其中一种 无法获得对应表单的原因有很多 只能在今后的道路上慢慢采坑然后避免 问题代码示例 import React Compone
  • Retrofit中的注解原理项目实战

    今天我们来聊聊这个最近很火的网络请求库retrofit 在此基础上会延伸出一些列的知识点 现在关于retrofit的文章很多 我之所以写这篇文章的原因在于 8月份负责假设新客户端底层的过程中首次尝试使用该库 并取得非常不错的效果 不到20天
  • 计算机视觉最新技术:YOLOv8等前沿算法推荐!

    计算机视觉最新技术 YOLOv8等前沿算法推荐 计算机视觉是人工智能领域中的一个重要方向 它涉及到图像 视频等多媒体形式的信息处理 而随着人工智能技术的不断发展 计算机视觉领域也不断涌现出新的算法和模型 其中 YOLOv8等一系列算法被认为
  • 初识springcloud(微服务)

    1 微服务的定义 microservice 1 多个微服务开发的依然是一个完整的应用 2 微服务都会独立运行在一个独立的进程里面 3 微服务之间通常会采用轻量级的通信机制来进行通信 比如http https socket netty dub
  • python 视频流分析,通过ffmpeg管道将视频输出流到Python脚本中进行分析。如何导入python?...

    我正在与其他库一起编写一个脚本 它需要RGB24格式的帧或图像 为了提高兼容性 我决定允许外部管道将帧流式传输到这个程序中 每次在代码中使用更改设备或源代码可能会变得乏味 使用解析器简单地指定源代码会导致语法错误 示例 ffmpeg f d
  • python如何更新包

    python如何更新包 更多python视频教程请到菜鸟教程https www piaodoo com Python安装新包 pip是很好用的安装工具 pip list 可以查询所有已安装的包和版本 怎么知道本地安装包的版本是否有可以更新的
  • Python模拟智能开关设备MQTT接入阿里云物联网平台 - PyCharm paho.mqtt

    概要 Python 使用 paho mqtt 库 利用阿里云物联网平台的设备证书 productKey deviceName deviceSecret 自动合成 userName passWord 以MQTT通信协议接入阿里云物联网平台 并
  • IPFS搭建私有网络

    87条消息 IPFS 节点搭建 躺在家里不干活的博客 CSDN博客 ipfs节点搭建 一 安装go ipfs 1 下载 下载地址https gitee com wang ya nan go ipfs releases wget https
  • Hadoop Spark 常见问题【一】

    Spark 1 RDD 数据集拆分 数据存储在内存或者磁盘 多分区 失效自动重构 转换操作构造 2 RDD俩种依赖 窄依赖 父RDD中的分区最多只能被一个子RDD的一个分区使用 和宽依赖 子RDD依赖于所有父RDD 3 spark 角色 1
  • APS高级计划排程系统和生产排产系统

    一 什么是APS系统 高级计划与排程APS Advanced Planning and Scheduling 是指在考虑生产资源约束的前提下 通过优化方法 为生产加工任务精确安排生产资源和计划生产时间 使生产及时完成 并使资源充分利用 AP
  • 【WebRTC 02】从摄像头获取视频以及切换分辨率和视频源

    上一节中我们已经搭建出了用于操作的环境 这一节我们要实现的一个小目标 就是将电脑摄像头拍到的内容实时显示到网页上 同时我们一起学习下原理 并做一些小拓展 文章目录 操作环境 实现效果 几个概念 HTML5中的Audio和Video API
  • C++项目练手:矩阵类的功能实现

    C 项目练手 矩阵类的功能实现 C 课程设计 矩阵类的相关功能实现 矩阵简述 实数矩阵是由一个按照长方阵列排列的实数集合 除数据外 两个实数矩阵可以进行加法和乘法运算 一个矩阵也可以和一个实数相乘 得到一个新的矩阵 请基于抽象出的矩阵的属性
  • JavaScript进阶之高阶函数(Higher-order function)

    你还在以为 map reduce filter 是高阶函数吗 高阶函数听上去很让人不明觉厉 但其实也并没有什么特别厉害的地方 只是网上的定义一直让我们有点模糊而已 接下来我们来详细讲讲 首先是定义 查自百度百科 定义 在数学和计算机科学中
  • 二进制安装docker

    二进制安装docker文档 建模部署 docker安装 下载docker 因rpm包安装依赖较多 选择二进制安装 下载地址如下 https download docker com linux static stable x86 64 创建d
  • 区域生长

    转自 https blog csdn net qq 37764129 article details 81227091 注 本程序只能做图像分割 结果图是转自原作者的 暂时没实现该功能 1 理论基础 区域生长算法的基本思想是将有相似性质的像
  • 称重问题递归解法

    用天平称重时 我们希望用尽可能少的砝码组合称出尽可能多的重量 如果只有5个砝码 重量分别是1 3 9 27 81 则它们可以组合称出1到121之间任意整数重量 砝码允许放在左右两个盘中 本题目要求编程实现 对用户给定的重量 给出砝码组合方案
  • 【小沐学NLP】Python实现中文、英文分词

    NLP开发系列相关文章编写如下 1 小沐学NLP Python实现词云图 2 小沐学NLP Python实现图片文字识别 3 小沐学NLP Python实现中文 英文分词 4 小沐学NLP Python实现聊天机器人 ELIZA 5 小沐学
  • win10 提供管理员权限才能删除文件夹

    计算机管理员帐户 也就是我们熟知的 Administrator 拥有可执行影响其他用户操作的权限 由于win10专业版刚发布 很多用户不知道怎么取得管理员权限 接下来小编就跟大家分享启用管理员权限的方法 1 打开win10专业版的开始菜单中
  • 手把手教你--JAVA微信支付(H5支付)

    概述 之前说过 有时间把微信支付的H5支付讲解下 一直拖了半年时间 最近的项目正好又温习了支付功能 趁着热乎 抓紧起来 微信的H5支付 相对公众号支付 容易了跟多 很多相似的东西 也有不同之处 这里只介绍H5支付的关键点 其他内容请先去看我
  • linux系统编程:线程同步-信号量(semaphore)

    线程同步 信号量 semaphore 生产者与消费者问题再思考 在实际生活中 只要有商品 消费者就可以消费 这没问题 但生产者的生产并不是无限的 例如 仓库是有限的 原材料是有限的 生产指标受消费指标限制等等 为了进一步 解决好生产者与消费