You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无名信号量的实现、存储及与无名管道的区别,sem_init参数解析

无名信号量的实现与sem_init函数解析

一、无名信号量的实现、存储位置与无名管道的区别

实现方式

无名信号量是用于同步的轻量级原语,底层依赖内核提供的原子操作和等待队列机制:

  • 线程间同步时,内核仅需保证对信号量计数的修改是原子性的,无需额外跨进程隔离处理。
  • 进程间同步时,内核会将信号量的核心数据(计数、等待队列关联信息)绑定到共享内存区域,确保多个进程能访问到同一个信号量实例。

存储位置

  • 线程间使用:可存储在进程私有内存的任意位置——全局变量区、栈上的局部变量、堆内存都可以,只要所有需要同步的线程能访问到这个sem_t变量的地址就行。
  • 进程间使用:必须放在进程间共享的内存区域,比如mmap创建的匿名共享内存、System V共享内存段,因为不同进程的私有内存空间相互隔离,只有共享内存能让多个进程指向同一个信号量实例。

和无名管道的差异

完全不同:

  • 无名管道是字节流通信机制,内核维护缓冲区用于父子进程间传递数据,核心是数据传输。
  • 无名信号量是同步协调工具,没有数据传输功能,仅通过维护一个计数实现多个执行单元(线程/进程)的等待、唤醒逻辑,核心是执行顺序的协调。

二、sem_init函数参数详解

函数原型:

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

sem指针的作用与传入要求

sem是指向sem_t类型变量的指针,这个变量会被内核用来存储信号量的核心状态(比如当前计数、等待队列的引用)。你需要传入一个已经分配好内存的sem_t变量的地址:

  • 线程间同步:可以传全局sem_t变量的地址、栈上局部sem_t变量的地址,或者用malloc在堆上分配的sem_t变量地址。
  • 进程间同步:必须传共享内存区域中sem_t变量的地址,否则其他进程无法访问到这个信号量实例。

pshared的含义与实现逻辑

  • 含义:pshared指定信号量的共享范围:
    • pshared = 0:信号量仅在当前进程的线程间共享,属于线程私有信号量。
    • pshared != 0:信号量可用于多个进程间的同步,属于进程间共享信号量。
  • 实现细节:
    • 线程间共享场景:内核只需要保证对信号量计数的修改是原子操作(比如CPU原子指令),因为同一进程的线程共享地址空间,直接访问sem指向的内存即可。
    • 进程间共享场景:内核会将信号量的状态与共享内存区域绑定,确保多个进程访问的是同一个内核维护的信号量对象,同时通过跨进程的同步机制(比如内核级锁)保证计数修改的安全性。

内容的提问来源于stack exchange,提问作者satwik das

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 11:01:33