信号量 - semaphore

房东的猫 提交于 2020-03-22 17:12:27

一. 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, ...);

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!