信号量 - semaphore

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

猜你喜欢

转载自www.cnblogs.com/blackandwhite/p/12545250.html