一. POSIX - 信号量
#include <semaphore.h> sem_t sem; ///< 信号量
信号量,分为有名信号量 和无名信号量。
有名信号量由sem_open/sem_close/sem_unlink创建/关闭/销毁,用于进程间通信。
无名信号量由sem_init/sem_destroy创建/销毁,用于线程间通信。
1. 信号量初始化
/*********************************************************** * @param[sem] 非命名信号量,只能被sem_destroy()销毁, * @param[pshared] 非0表示进程间通信信号量,但是Linux系统暂未实现这一功能(实现方式为共享内存),0表示线程间通信信号量。 * @param[value] 信号量初始化值 * @return 成功返回0,失败返回-1及设置错误码errno *//********************************************************/ int sem_init(sem_t * sem, int pshared, unsigned vlaue);
/*********************************************************** * @param[sem] 命名信号量,只能被sem_close()关闭 有名信号量是随内核持续的,实现是以共享内存实现的. * @param[name] 信号量名字, 相同名字返回相同的信号量地址, name参数的构造是以 “ / ” 号开头,后面跟的字符串不能再有 “ / ” 号 * @param[oflag] 标志位, O_CREAT: 信号量不存在,就创建,参数mode,value才有效;信号量存在, 该标志位无效 O_EXCL: 与o_CREAT连用,信号量存在,就返回失败* @param[mode] 创建信号量的权限, 例如:0664(八进制)* @param[value] 创建信号量的值 * @return 成功返回信号量的地址,失败返回SEM_FAILED及设置错误码errno *//********************************************************/ sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
2. 信号量释放及获取
/********************************************************** * @param[sem] 信号量* @param[abs_timeout] 真实时间 * @return 成功返回0,失败返回-1及设置错误码errno *//********************************************************/ int sem_post(sem_t * sem); ///< 释放信号量, 信号量值 +1 int sem_wait(sem_t * sem); ///< 获取信号量,如果信号量值为0, 会一直阻塞,否则信号量值 -1, int sem_trywait(sem_t * sem); ///< 尝试获取信号量,如果信号量值为0,会立即返回值,并不会阻塞int sem_timedwait(sem_t * sem, const struct timespec * abs_timeout); ///< 限时获取信号量,如果信号值为0,会阻塞,截止时间是abs_timeou
3. 销毁信号量
/*********************************************************** * @brief 只能销毁sem_init创建的信号量 * @param[sem] 信号量 * @return 成功返回0, 失败返回-1,并设置错误码errno *//********************************************************/ int sem_destroy(sem_t * sem);
/*********************************************************** * @brief 只能销毁sem_open创建的命名信号量 * @param[sem] 信号量 * @return 成功返回0, 失败返回-1,并设置错误码errno *//********************************************************/ int sem_close(sem_t * sem);
/*********************************************************** * @brief 移除命名信号量和name之间的关联 * @param[sem] 信号量 * @return 成功返回0, 失败返回-1,并设置错误码errno *//********************************************************/ int sem_unlink(const char *name);
二. System V - 信号量
#include <sys/sem.h>
1. 创建信号量
/** * @param[key] IPC键值, 可以由ftok()生成 * @param[nsems] 信号量集合中包含的信号量数目 * @param[semflg] 标志位 IPC_CREAT IPC_EXCL 0664 * @return 成功返回信号量集合标识符,错误返回-1及设置错误码errno */ int semget(key_t key, int nsems, int semflg);
2. 信号量操作
/** struct sembuf */ struct sembuf { short sem_num; ///< 信号量, 操作信号量在信号集中的编号,编号从0开始 short sem_op; ///< 信号量操作, P(-1 等待信号量, 如果为0则阻塞), V(+1 释放信号量) short sem_flg; ///< 操作标志位 IPC_NOWAIT(操作不满足,不会阻塞), IPC_UNDO(不管程序是否正常结束,保证信号量值都为调用semop调用前的值) }; /** * @brief * @param[semid] 信号量标识符 * @param[sops] 信号量操作数组 * @param[nops] 信号量操作数组的大小 * @return 成功返回0,失败返回-1及设置错误码errno */ int semop(int semid, struct sembuf *sops, size_t nops);
3. 信号量控制
/** union semun */ union semun { int val; struct semid_ds *buf; unsigned short *array; }; /** * @brief 信号量控制 * @param[semid] 信号量标识符 * @param[semmun]信号量集合中的顺序编号,编号从0开始 * @param[cmd]命令 IPC_STAT 获取信号量的semid_ds结构,结果存放在第四个参数中的buf中 IPC_SET 设置第四个参数中的buf值(sem_perm.uid, sem_perm.gid, sem_perm.mode)为信号量标识符的值 IPC_RMID 移除信号量,当信号量集合中所有信号量都移除后,就销毁信号量集。 * @param[...] 第四个参数,参数结构为union semun,一般需要自定义 * @return 成功返回与cmd有关的值, 失败返回-1及设置错误码errno */ int semctl(int semid, int semnum, int cmd, ...);
来源:https://www.cnblogs.com/blackandwhite/p/12545250.html