sem_init的概念和使用案例

news/2025/1/31 19:46:54/

sem_init 是 POSIX 线程库中用于初始化未命名信号量(unnamed semaphore)的函数,常用于多线程或多进程间的同步。以下是其概念和使用案例的详细说明:


概念

  • 函数原型
     #include <semaphore.h>int sem_init(sem_t *sem, int pshared, unsigned int value);
    
  • 参数
    • sem:指向信号量对象的指针。
    • pshared:决定信号量的共享范围:
      • 0:信号量在线程间共享(同一进程内)。
      • 0:信号量在进程间共享(需配合共享内存使用)。
    • value:信号量的初始值(通常表示可用资源的数量)。
  • 返回值
    • 成功返回 0,失败返回 -1 并设置 errno

使用案例

场景 1:多线程同步(线程间共享)
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>sem_t sem;
int shared_resource = 0;void* thread_func(void* arg) {sem_wait(&sem); // 等待信号量shared_resource++; // 访问共享资源printf("Thread %ld: shared_resource = %d\n", (long)pthread_self(), shared_resource);sem_post(&sem); // 释放信号量return NULL;
}int main() {pthread_t t1, t2;// 初始化信号量(线程间共享,初始值为1)if (sem_init(&sem, 0, 1) == -1) {perror("sem_init failed");return 1;}pthread_create(&t1, NULL, thread_func, NULL);pthread_create(&t2, NULL, thread_func, NULL);pthread_join(t1, NULL);pthread_join(t2, NULL);sem_destroy(&sem); // 销毁信号量return 0;
}
场景 2:多进程同步(进程间共享)

需将信号量放置在共享内存中:

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <semaphore.h>int main() {// 创建共享内存int fd = shm_open("/my_shm", O_CREAT | O_RDWR, 0666);ftruncate(fd, sizeof(sem_t));sem_t *sem = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);// 初始化信号量(进程间共享,初始值为1)if (sem_init(sem, 1, 1) == -1) {perror("sem_init failed");return 1;}// 父子进程示例if (fork() == 0) {sem_wait(sem);printf("Child process: Accessing resource\n");sem_post(sem);_exit(0);} else {sem_wait(sem);printf("Parent process: Accessing resource\n");sem_post(sem);wait(NULL);}sem_destroy(sem);    // 销毁信号量shm_unlink("/my_shm"); // 清理共享内存return 0;
}

注意事项

  1. 未命名 vs 命名信号量

    • sem_init 用于未命名信号量,生命周期由程序控制。
    • 命名信号量(通过 sem_open 创建)可用于无亲缘关系的进程间同步。
  2. 废弃警告

    • 在较新的系统(如 Linux 2.6+),sem_init 已被标记为废弃,建议改用 sem_open + sem_unlink
  3. 资源释放

    • 必须调用 sem_destroy 释放信号量资源,避免内存泄漏。
  4. 编译命令

    gcc program.c -pthread -lrt  # 链接 pthread 和 rt 库(进程间共享需要)
    

通过合理使用 sem_init,可以实现线程或进程间的同步控制(如互斥锁、资源计数等)。


http://www.ppmy.cn/news/1568223.html

相关文章

服务器机房迁移,centos系统root无法登录,也无法联网等问题

介绍 服务器迁移之后问题太多了&#xff0c;就关了一次机而已。开机之后root也没法登录&#xff0c;网络也无法访问。这个问题我们整整修复了两天两夜。废话不多说了。过程就不记录了&#xff0c;直接写方法&#xff0c;以免下次再遇到此问题。 问题记录 root账号无法登录 …

JavaScript系列(43)--依赖注入系统实现详解

JavaScript依赖注入系统实现详解 &#x1f489; 今天&#xff0c;让我们深入探讨JavaScript的依赖注入系统实现。依赖注入是一种设计模式&#xff0c;它通过将依赖关系的创建和管理从代码中分离出来&#xff0c;提高了代码的可维护性和可测试性。 依赖注入基础概念 &#x1f…

TVS选型设计

TVS选型距离 以实际的案例举例。电路的正常工作电压VCC是24V&#xff0c;最高工作电压Vmax是26V,后级电路可承受的最高瞬态电压为50V&#xff0c;实验的测试波形为 8/20μs波形&#xff0c;测试电压500V&#xff0c;测试电源内阻及PPTC的静态电阻合计为2Ω。根据上述信息选择合…

【SpringMVC】——Json数据交互处理

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

用 Scoop 优雅管理 Windows 软件:安装、配置与使用全指南

本篇将主要讲讲如何用「Scoop」优雅管理 Windows 软件&#xff1a;安装、配置与使用全指南 一、Scoop 是什么&#xff1f; Scoop 是一款专为 Windows 设计的命令行软件包管理工具&#xff0c;它能让你像 Linux 系统一样通过命令快速安装、更新和卸载软件。其核心优势包括&…

Jenkins下载 Maven、Allure 插件并且配置环境

文章目录 Jenkins在插件中心下载 maven、allure插件maven插件下载allure插件下载 配置maven、allure 往期推荐&#xff1a; 最新! 在 Linux上搭建Jenkins环境! Jenkins邮件通知的详细配置含邮件通知模板&#xff01; Jenkin配置企业微信通知 Jenkins在插件中心下载 maven、…

[C语言日寄] <stdio.h> 头文件功能介绍

在C语言的世界里&#xff0c;<stdio.h> 是一个极其重要的头文件&#xff0c;它提供了标准输入输出功能&#xff0c;是C语言程序与用户交互的核心工具。今天&#xff0c;我们就来深入探讨 <stdio.h> 的功能、使用注意事项以及它的拓展应用。 功能介绍 <stdio.h…

Python设计模式 - 组合模式

定义 组合模式&#xff08;Composite Pattern&#xff09; 是一种结构型设计模式&#xff0c;主要意图是将对象组织成树形结构以表示"部分-整体"的层次结构。这种模式能够使客户端统一对待单个对象和组合对象&#xff0c;从而简化了客户端代码。 组合模式有透明组合…