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

多线程--sem_wait(sem)特殊用法

1一般用法
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>sem_t sem;
int shared_data = 0; // 共享资源void *thread_func(void *arg) {// 获取信号量(P操作):进入临界区sem_wait(&sem);// 临界区操作shared_data++;printf("线程 %d:shared_data = %d\n", *((int*)arg), shared_data);// 释放信号量(V操作):离开临界区sem_post(&sem);return NULL;
}int main() {pthread_t tid1, tid2;int id1 = 1, id2 = 2;// 初始化二进制信号量(初始值1)sem_init(&sem, 0, 1);// 创建两个线程pthread_create(&tid1, NULL, thread_func, &id1);pthread_create(&tid2, NULL, thread_func, &id2);// 等待线程结束pthread_join(tid1, NULL);pthread_join(tid2, NULL);// 销毁信号量sem_destroy(&sem);return 0;
}
2. 合理场景:主线程等待子线程完成初始化

若主线程需要等待子线程完成某些初始化操作后再继续执行,可在 main 中调用 sem_wait 阻塞等待,子线程初始化完成后调用 sem_post 唤醒主线程。

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>sem_t sem;// 子线程:完成初始化后释放信号量
void *init_thread(void *arg) {printf("子线程:正在初始化...\n");// 模拟初始化操作sleep(2);printf("子线程:初始化完成\n");// 释放信号量,唤醒主线程sem_post(&sem);return NULL;
}int main() {pthread_t tid;// 初始化信号量,初始值为0(主线程会先阻塞)sem_init(&sem, 0, 0);// 创建子线程执行初始化pthread_create(&tid, NULL, init_thread, NULL);// 主线程等待初始化完成(此时信号量为0,主线程阻塞)printf("主线程:等待初始化...\n");sem_wait(&sem);  // 放在main函数中,阻塞等待子线程唤醒// 初始化完成后,主线程继续执行printf("主线程:开始执行后续逻辑\n");pthread_join(tid, NULL);sem_destroy(&sem);return 0;
}
3 特殊场景:主线程控制子线程的并发数量

若主线程负责创建多个子线程,并通过信号量限制同时运行的子线程数量,sem_wait 可放在主线程的创建循环中。

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>#define MAX_CONCURRENT 2
sem_t sem;void *worker(void *arg) {int id = *(int*)arg;printf("线程 %d:开始工作\n", id);sleep(1);  // 模拟工作printf("线程 %d:工作结束\n", id);sem_post(&sem);  // 释放信号量,允许主线程创建新线程return NULL;
}int main() {sem_init(&sem, 0, MAX_CONCURRENT);  // 初始值2,最多2个线程同时运行pthread_t tids[5];int ids[5] = {1,2,3,4,5};for (int i = 0; i < 5; i++) {sem_wait(&sem);  // 主线程等待信号量(控制并发)pthread_create(&tids[i], NULL, worker, &ids[i]);}// 等待所有线程结束for (int i = 0; i < 5; i++) {pthread_join(tids[i], NULL);}sem_destroy(&sem);return 0;
}
http://www.lryc.cn/news/591349.html

相关文章:

  • 【原创】【图像算法】高精密电子仪器组装异常检测
  • 24、鸿蒙Harmony Next开发:不依赖UI组件的全局自定义弹出框 (openCustomDialog)
  • java之json转excel生成
  • AppTrace:重新定义免填邀请码,解锁用户裂变新高度
  • IMU噪声模型
  • JxBrowser 7.43.5 版本发布啦!
  • ubuntu 开启ssh踩坑之旅
  • 加速度传感器方向校准方法
  • 原生前端JavaScript/CSS与现代框架(Vue、React)的联系、区别与运行环境(精简版)
  • 关于用git上传远程库的一些常见命令使用和常见问题:
  • Python爬虫入门到实战(2)-selenium驱动浏览器
  • 静态住宅IP和节点有什么区别?哪种更适合你的需求?
  • Redis完全指南:从基础到实战(含缓存问题、布隆过滤器、持久化及Spring Boot集成)
  • redis速记
  • 【WPF】WPF 自定义控件之依赖属性
  • springboot打包二次压缩Excel导致损坏
  • 【Linux基础知识系列】第五十四篇 - 网络协议基础:TCP/IP
  • 深入GPU硬件架构及运行机制
  • 鸿蒙UI自动化测试框架Hypium的使用指南
  • springboot跨域问题 和 401
  • 解锁数据分析:从基础概念到核心指标的全面指南
  • 数据分析:从数据到决策的核心逻辑与实践指南
  • 电脑DLL错误修复dll微软运行库工具修复dll缺失找不到dll等问题,dll免费修复工具
  • Servlet概述
  • 基于arduino单片机汽车智能电子防碰撞装置设计
  • linux_线程同步
  • 一文掌握Harbor的配额管理和GC机制
  • 2025测绘程序设计国赛实战 | 泰森多边形算法C#实现
  • 华为云容器产品分析
  • tcp/udp调试工具