system V信号量
目录
创建信号量
删除信号量
并发编程概念
信号量
信号量PV通信
System V 是如何实现IPC的,和管道有什么不同
作为和消息队列,共享内存同一个差不多的通信手段,信号量也是一种通信方式。涉及到信号量的函数都是以sem开头的。
创建信号量
semget
是 System V 信号量(semaphore)相关的系统调用,用于创建或获取一个信号量集合(semaphore set)。
都差不多,我们可以一次创建多个信号量进行通信
删除信号量
...默认不需要,所以就三个参数。
semnum
是信号量集合中的索引,如果你的信号量集合里只有一个信号量,那么 semnum
填 0
。
如果 semget(key, nsems, semflg);
创建了 nsems
个信号量,那么 semnum
的取值范围是 0 ~ nsems-1
,即第 i
个信号量的 semnum
是 i
。
查看信号量,可以使用系统调用ipcs -s
这个信号量涉及的函数比较复杂!!!
并发编程概念
多个执行流(进程)能看到的同一份资源称为共享资源,被保护起来的资源加做临界资源,也就是说临界资源只允许在一个时间点有一个进程进行访问,所以我们保护的方式常见的是:互斥和同步,任何时刻只允许一个执行流访问资源叫做互斥,多个执行流访问临界资源的时候,具有一定的顺序性叫做同步,我们前面给共享内存加命名管道进行保护就是完美的解决了互斥和同步的问题。
保护临界区资源还得加锁保护,两个临界区之间的非临界区加锁和解锁,加锁保护临界区。
信号量
信号量和信号没有关系,什么是信号量呢,我们可以认为信号量是一个计数器,今天,A,B两个进程访问一整个空间,这时资源被当成整体进行使用,但是根据同步互斥观点来看只能单次一个进程进行访问,那如何分配给多个进程呢,这时资源不看成整体的而是分成n分,那n份资源一次就可以供给n个进程同时进行通信,不同进程访问共享资源使其具有一定的并发性,但如果今天来了n + 1个进程怎么办,过量的进程进入临界资源势必照成不好的结果,所以我们引入计数器信号量进行保护,当资源被分为n份时,count初始值为n来一个进程通信,count--,直到count == 0时就不让进来了,我们也可以看出system V IPC资源的生命周期是随内核的。到现在我们才理解了一半,进程不一定非要访问资源,计数器才--,进程只需要告诉计数器我需要这个空间就可以了,所以本质是一种对资源的预定,最后进程对资源的争抢就转化为对count的争抢,进程就算没有访问资源,只要抢夺了一个计数,那内核就需要开辟一个属于我的资源。所以sem可以有很多个,创建信号量是以信号集的方式提供给使用者的,所以创建函数里面的semnum就是这么来的。count等待计数的过程称为P操作,释放计数(count++)的过程就是V操作,PV操作体现了原子性。
当这个count具有二元非0即1的状态时,二元信号量就是锁。
信号量PV通信
semop
是 System V 信号量的操作函数,用于 P(等待)和 V(释放)操作,可以对信号量进行增减操作,实现进程间同步。
可以通过设置sembuf里面的参数进行改变操作类型。
sops是一个指向结构体数组的指针,所以可以同时对多个信号量进行PV操作。创建信号量就是减少计数的操作。
System V 是如何实现IPC的,和管道有什么不同
System V 提供了消息队列、共享内存和信号量三种进程间通信(IPC)机制,它们依赖内核对象进行管理,使用 key
作为标识,并支持权限控制。与管道(Pipe)相比,System V IPC 适用于任意进程通信,而管道主要用于父子进程。System V IPC 具有持久化特性,即使进程退出,IPC 资源仍然存在,直到显式删除;而管道的生命周期依赖进程,进程终止时管道自动销毁。此外,System V IPC 需要手动同步,如共享内存需要信号量控制访问,而管道在写满或读空时会自动同步。System V IPC 的核心数据结构是 kern_ipc_perm
,其中包含 key
、id
、权限信息等,每种 IPC 机制都基于该结构。例如,消息队列通过 msg_queue
结构管理消息链表,支持多进程异步通信;共享内存由 shmid_kernel
结构维护,多个进程可以直接映射同一块物理内存,提高数据交换效率;信号量通过 sem_array
结构管理信号量数组,实现资源访问控制。内核通过 do_msgsnd()
、do_msgrcv()
处理消息队列,do_shmat()
、do_shmdt()
处理共享内存映射,do_semop()
负责信号量 P/V 操作。相较而言,管道基于文件描述符,通信方式是流式数据传输,受限于缓冲区大小,且仅支持单向通信。综合来看,System V IPC 更适用于需要高效、跨进程的通信,如共享内存提供最快速的进程间数据交换,消息队列适用于异步消息传递,而信号量用于进程同步和资源管理。
System V IPC 设计比较老旧,管理复杂,特别是信号量(semctl
、semop
)在高并发场景下性能较差,手动清理资源也容易出错,过多研究底层无意义。