有三種信號量:函數
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.