computer_knowledge_notes/Languages/CLang/libraries/sys/sem.md

99 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#### 概述
SYS V信号量。
SYS V信号量是System V进程间通信的一部分。System V进程间通信的方式包括消息队列、信号量和共享内存。
`semid_ds`描述了一组信号量,它定义在`bits/sem.h`
```c
/* Data structure describing a set of semaphores. */
struct semid_ds {
struct ipc_perm sem_perm; /* Ownership and permissions */
time_t sem_otime; /* Last semop time */
time_t sem_ctime; /* Last change time */
unsigned long sem_nsems; /* No. of semaphores in set */
};
struct ipc_perm {
key_t __key; /* Key supplied to semget(2) */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions */
unsigned short __seq; /* Sequence number */
};
```
#### 相关函数
```c
/* System V信号量集合里的每个信号量都有如下相关变量(由内核维护,仅内核可见) */
unsigned short semval; /* semaphore value */
unsigned short semzcnt; /* # waiting for zero */
unsigned short semncnt; /* # waiting for increase */
pid_t sempid; /* PID of process that last */
/* sembuf定义了对单个信号量的操作 */
struct sembuf{
unsigned short int sem_num; /* 要操作的信号量在信号量集合中的编号 */
short int sem_op; /* 信号量操作正数是V操作负数是P操作 */
short int sem_flg; /* 操作标志符 */
// 可接受的sem_flg:IPC_NOWAIT and SEM_UNDO
// SEM_UNDO - 由进程自动释放信号量
// IPC_NOWAIT - 不阻塞
};
/* semctl()第四个参数的数据类型 */
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO(Linux-specific) */
};
/* 功能System V信号量集合的控制操作。
* semid要控制的信号量所在的信号量集合。
* semnum要控制的信号量在信号量集合中的序号。(从0开始编号。)
* cmd对信号量的控制操作。
* IPC_RMID - 0, 删除标识符
* IPC_SET - 1, 设置ipc_perm选项
* IPC_STAT - 2, 获取ipc_perm选项
* IPC_INFO - 3, See ipcs
* GETPID - 11, get sempid
* GETVAL - 12, get semval
* GETALL - 13, get all semval's
* GETNCNT - 14, get semncnt
* GETZCNT - 15, get semzcnt
* SETVAL - 16, set semval
* SETALL - 17, set all semval's
* 第四个参数的类型为union semun此参数是否存在取决于第三个参数cmd。
*/
int semctl(int semid, int semnum, int cmd, ...);
/* 功能获取System V信号量集合的描述符。semop()和semctl()会使用它。
* key返回的信号量集合描述符是与本参数相关联的一个key只对应一个固定的描述符。
* IPC_PRIVATE私有的key。
* nsems信号量集合里的元素数。
* semflg
* IPC_CREATE如果key不存在则创建之。(01000)
* IPC_EXCL如果key存在则报错。(02000)
* IPC_NOWAITReturn error on wait.(04000)
* 返回值:成功则返回信号量集合的描述符(非负整数);失败则返回-1。
*/
int semget(key_t key, int nsems, int semflg);
/* 功能System V信号量操作。即P/V操作。
* semid信号量集合的描述符。执行semctl()函数可得。
* sops是一个数组指针这个数组的元素是结构体sembuf。
* nsops数组spos里的元素要操作的元素的数量。
*/
int semop(int semid, struct sembuf *sops, size_t nsops);
```
#### 参考文档
- [linengier - Linux系统编程之信号量](https://www.cnblogs.com/linengier/p/9399880.html#:~:text=%E5%9C%A8%E5%AD%A6%E4%B9%A0%E4%BF%A1%E5%8F%B7%E9%87%8F%E4%B9%8B%E5%89%8D%EF%BC%8C%E6%88%91%E4%BB%AC%E5%BF%85%E9%A1%BB%E5%85%88%E7%9F%A5%E9%81%93%E2%80%94%E2%80%94Linux%E6%8F%90%E4%BE%9B%E4%B8%A4%E7%A7%8D%E4%BF%A1%E5%8F%B7%E9%87%8F%EF%BC%9A%20%EF%BC%881%EF%BC%89,%E5%86%85%E6%A0%B8%E4%BF%A1%E5%8F%B7%E9%87%8F%EF%BC%8C%E7%94%B1%E5%86%85%E6%A0%B8%E6%8E%A7%E5%88%B6%E8%B7%AF%E5%BE%84%E4%BD%BF%E7%94%A8%20%EF%BC%882%EF%BC%89%20%E7%94%A8%E6%88%B7%E6%80%81%E8%BF%9B%E7%A8%8B%E4%BD%BF%E7%94%A8%E7%9A%84%E4%BF%A1%E5%8F%B7%E9%87%8F%EF%BC%8C%E8%BF%99%E7%A7%8D%E4%BF%A1%E5%8F%B7%E9%87%8F%E5%8F%88%E5%88%86%E4%B8%BAPOSIX%E4%BF%A1%E5%8F%B7%E9%87%8F%E5%92%8CSYSTEMV%E4%BF%A1%E5%8F%B7%E9%87%8F%E3%80%82)