当前位置: 首页 > news >正文

linux——信号量

1.头文件-semaphore.h

2.信号量类型

  • sem_t sem;
  • 加强版的互斥锁

3.主要函数

  • 初始化信号量

em_init(sem_t *sem,int pshared,unsigned int value);

0-线程同步

1-进程同步

value-最多有几个线程操作共享数据

  • 销毁信号量

sem_destroy(sem_t *sem);

  • 加锁

sem_wait(sem_t *sem);

调用一次相当于对sem做了一次 -- 操作

如果sem值为0,线程会阻塞

  • 尝试加锁

sem_trywait(sem_t *sem);

sem == 0;加锁失败,不阻塞,直接发

  • 限时尝试加锁

sem_timewait(sem_t *sem,xxxx);

  • 解锁++

sem_post(sem_t *sem);

对sem做了++ 操作

4.练习

使用信号量实现生产者,消费者模型。

#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<pthread.h> #include<semaphore.h> sem_t producer_sem; sem_t customer_sem; typedef struct node { int data; struct node* next; }Node; Node* head = NULL; void* producer(void* arg) { while(1) { sem_wait(&producer_sem); //-- =0 Node* node = (Node*)malloc(sizeof(Node)); node->data = rand()%1000; node->next = head; head = node; printf("producer:%ld,%d\n",pthread_self(),node->data); sem_post(&customer_sem); //customer_sem ++ sleep(rand()%5); } return NULL; } void* customer(void* arg) { while(1) { sem_wait(&customer_sem); //0 Node* del = head; head = head->next; printf("customer:%ld,%d\n",pthread_self(),del->data); free(del); sem_post(&producer_sem); //producer ++ sleep(rand()%5); } return NULL; } int main() { pthread_t thid[2]; sem_init(&producer_sem,0,4); sem_init(&customer_sem,0,0); pthread_create(&thid[0],NULL,producer,NULL); pthread_create(&thid[1],NULL,customer,NULL); for(int i = 0;i < 2;i++) { pthread_join(thid[i],NULL); } sem_destroy(&producer_sem); sem_destroy(&customer_sem); return 0; }

①先告诉你:这代码在干嘛?

  • 生产者:生产节点,插入链表
  • 消费者:消费节点,删除链表
  • 限制链表最多存 4 个节点(满了就不能生产)
  • 实现:用信号量控制生产、消费的节奏

②先讲核心:什么是信号量?

信号量 = 一个计数器 + 等待队列

两个最核心操作:

  1. sem_wait( sem )

    • 计数器-1
    • 如果计数器 < 0,线程阻塞等待
  2. sem_post( sem )

    • 计数器+1
    • 如果有等待的线程,唤醒一个

③两个信号量的作用

sem_t producer_sem; // 表示“空闲位置”,最多4个 sem_t customer_sem; // 表示“已有产品数量”,初始0
  • producer_sem = 4→ 链表最多放4 个节点
  • customer_sem = 0→ 一开始链表空的,没有产品

④main函数初始化信号量

sem_init(&producer_sem, 0, 4); sem_init(&customer_sem, 0, 0);
  • 第 1 个参数:信号量变量
  • 第 2 个参数:0 = 线程间使用
  • 第 3 个参数:初始值

⑤生产者线程

void* producer(void* arg) { while(1) { sem_wait(&producer_sem); // 空闲位置 -1

sem_wait(&producer_sem)

  • 空闲位置减 1
  • 如果减到 < 0 →生产者阻塞(链表满了,不能再生产)
// 生产节点 Node* node = (Node*)malloc(sizeof(Node)); node->data = rand()%1000; node->next = head; head = node; printf("producer:%ld,%d\n",pthread_self(),node->data);
sem_post(&customer_sem); // 产品数量 +1

sem_post(&customer_sem)

  • 产品数量+1
  • 唤醒等待的消费者
sleep(rand()%5); } return NULL; }

⑥消费者线程

void* customer(void* arg) { while(1) { sem_wait(&customer_sem); // 产品数量 -1

sem_wait(&customer_sem)

  • 产品数量-1
  • 如果 < 0 →消费者阻塞(链表空,没的消费)
// 消费(头删节点) Node* del = head; head = head->next; printf("customer:%ld,%d\n",pthread_self(),del->data); free(del);
sem_post(&producer_sem); // 空闲位置 +1

sem_post(&producer_sem)

  • 空闲位置+1
  • 唤醒阻塞的生产者
sleep(rand()%5); } return NULL; }

⑦整段代码运行流程

初始状态

producer_sem = 4customer_sem = 0

第 1 步

消费者执行sem_wait(customer)→ 0-1 = -1 →阻塞等待

第 2 步

生产者生产sem_wait(producer)→ 4-1=3生产完sem_post(customer)→ 0+1=1

第 3 步

消费者被唤醒消费完sem_post(producer)→ 3+1=4

第 4 步

如果生产者连续生产 4 次producer_sem 变成 0第 5 次生产时sem_wait阻塞

⑧这个代码实现了什么?

  1. 链表最多存 4 个节点

  2. 满了,生产者就等

  3. 空了,消费者就等

  4. 生产一个,才能消费一个

  5. 完全用信号量实现同步

版本输出特点核心问题
无锁版本生产、消费乱序,数字错乱、丢失线程不安全,数据竞争
互斥锁 + 条件变量版本生产一个、消费一个,严格交替,无连续生产 / 消费缓存为 0,生产后必须等消费,效率低
信号量版本(当前)可连续生产(最多 4 个)、连续消费,一一对应带缓存的生产者 - 消费者,效率更高
http://www.jsqmd.com/news/614948/

相关文章:

  • WinClaw实战教程 01|安全版OpenClaw从零部署:5分钟上手+全功能实测+避坑大全
  • 告别录屏!用FFmpeg+Git Bash一键下载m3u8视频(附完整命令)
  • 2026届毕业生推荐的六大AI辅助论文方案推荐榜单
  • 如何通过游戏决策辅助提升英雄联盟竞技表现?技术赋能的智能解决方案
  • OpenEMS:开源能源管理系统的架构解析与应用实践
  • 2026 铺路钢板厂家推荐排行榜:2 公分、3 公分铺路、不锈钢板优质商家盘点 - 海棠依旧大
  • C#怎么限制并发请求数_C#如何保护服务器接口【必备】
  • API 类别 - UI 核心
  • 2026届必备的降AI率平台推荐
  • OPCUA客户端UaExpert和S71500PLC通信使用详细介绍
  • 怎么批量文件搜索?搜索不到文件夹,搜索不到文件,批量搜索推荐
  • 2025最权威的AI写作网站横评
  • C 标准库 - `<ctype.h>`
  • 如何让 CSS Grid 自适应容器尺寸并保持固定宽高
  • 2026届学术党必备的十大AI论文工具实际效果
  • 2025最权威的降AI率助手解析与推荐
  • Redis命令处理机制源码探究词
  • 突破苹果触控板Windows限制:mac-precision-touchpad驱动实现原生级精准控制
  • 全能EVE舰船配置工具:Pyfa让你的太空冒险更高效
  • 稀缺资源!农业农村部试点项目PHP可视化配置规范白皮书(内部解密版·仅限本期订阅用户获取)
  • W3C CSS 活动
  • 2026AI搜索优化OEM卷王横评:5家源头厂家综合对比+采购避坑指南
  • 破局音乐格式枷锁:QMCDecode让你的音频文件重获自由
  • go 面向对象
  • G-Helper:华硕笔记本的轻量级控制中心,5分钟告别臃肿官方软件
  • 颠覆传统:3步实现华硕笔记本性能跃升的轻量级解决方案
  • Dify与Ollama容器化部署实战:从“max retries exceeded”报错到网络连通性深度解析
  • CSS如何实现动态间距调整_通过CSS变量控制padding与margin值
  • Π的进度条
  • 2026年3月涂胶定量机评测:这些口碑好的公司值得关注,行业内涂胶定量机找哪家甄选实力品牌 - 品牌推荐师