有三种信号量:函数
1,Posix有名信号量:使用PosixIPC名字标识(经过特定函数,调用一个绝对文件路径名做为参数,返回一个特定标识),可用于进程或线程间通讯。post
2,Posix基于内存的信号量:存放在共享内存区(进程间共享内存区或者线程间共享内存区),可用于进程或线程间同步。测试
3,System V信号量:在内核中维护,可用于进程或线程间的同步。线程
Posix信号量没必要在内核中维护的,这不一样于systemV信号量。code
那么信号量、互斥锁和条件变量之间的差别在哪呢?:进程
1,互斥锁必须老是由给它上锁的线程解锁,信号量的挂出却不用非得由执行它的等待操做线程执行。内存
2,互斥锁要么被锁住要么被解开(二值状态,相似于二值信号量)。get
下面咱们来说有名信号量:同步
因为进程间或者线程间同步。it
建立或者打开已有的有名信号量:
#include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For mode constants */ #include <semaphore.h> sem_t *sem_open(const char *name, int oflag); sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value); Link with -lrt or -pthread.
关闭和删除信号量:
#include <semaphore.h> int sem_close(sem_t *sem); int sem_unlink(const char *name); Link with -lrt or -pthread.
一个进程关闭了以后,内核会自动的对其上打开的的全部有名信号量自动执行关闭,但这并不表明就删除了此信号量。每一个信号量都有一个应用计数器记录当前的打开次数,当记录数大于0时,unlink就将其从文件系统中删除,可是其信号的析构要等到最后一个sem_close发生时为止。
获取信号量函数:
#include <semaphore.h> int sem_wait(sem_t *sem); int sem_trywait(sem_t *sem); int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); Link with -lrt or -pthread.
测试所指定的信号量值,若是此值等于0,那么线程就投入睡眠中,若是大于0,则将此值减一并返回。
释放信号量函数:
#include <semaphore.h> int sem_post(sem_t *sem); Link with -lrt or -pthread.
将制定的信号量加一,并唤醒正在等待该信号量值变为正数的全部线程。
这里还有一个函数:
#include <semaphore.h> int sem_getvalue(sem_t *sem, int *sval); Link with -lrt or -pthread.
经过sval得到当前信号量值,或者经过返回值要么是0,要么是此时阻塞在这个信号量上的进程或者线程数。
下面来说基于内存的信号量:
#include <semaphore.h> int sem_init(sem_t *sem, int pshared, unsigned int value); Link with -lrt or -pthread.
它们由应用程序分配一个信号量的内存空间,而后经过这个函数初始化它。
这里,涉及到是进程间共享的仍是线程间共享的要分两种看待:
1,进程间共享的:那么应用程序就应该在进程间共享内存区分配一个信号量的内存空间,同时shard的值为nonezero。
2,线程间共享的,那么应用程序就应该在线程间共享内存区分配一个信号量的内存空间,同时shared的值为zero。
释放基于内存的信号量:
#include <semaphore.h> int sem_destroy(sem_t *sem); Link with -lrt or -pthread.