Linux semaphore
sem_t 有一個 ≥0 的整數,sem_post() 將它加 1,sem_wait() 等候到 >0 時將讓它減一。另外還有 sem_trywait() 不等候,sem_timedwait() 等候到特定時間。
Linux semaphore 有兩種:memory-based 和 named。
- Memory-based,或稱非 named:在某個記憶體位置,透過 sem_init() 初始化、sem_destroy() 銷毀。依照記憶體位置的不同,又可分成 thread-shared semaphore 跟 process-shared semaphore。前者只要是單一 process 內的某個位址,旗下的 thread 都可以存取。後者需要放在不同 process 都可以存取的 shared memory (可透過 shmget()、shm_open()、或 mmap() 取得),或者 fork 的子程序繼承了記憶體對應,也可以存取。
- sem_init(sem_t *, int pshared, unsigned int value)
- sem_destroy()
- Named:有個名稱在 /dev/shm/sem.名稱,透過 sem_open() 建立或開啟、sem_close() 關閉、sem_unlink() 移除。
- sem_open()/sem_close()/sem_unlink()
sem_post()
sem_wait(sem_t *):回傳 0 表示等候到 semaphore 並減一。
sem_trywait(sem_t *):類似 sem_wait(),但 semaphore 為 0 時不等候,回傳 -1 及 errno = EAGAIN。
sem_timedwait(sem_t *, const struct timespec *):類似 sem_wait(),但最久只等候到某個 Epoch 時間,等候不到的話回傳 -1 及 errno = ETIMEDOUT。
sem_getvalue():取得目前 semaphore 值。
等候 semaphore 成功回傳 0;失敗 semaphore 不變,回傳 -1 並設 errno。
| errno | sem_wait() | sem_trywait() | sem_timedwait() |
| EINTR | signal 中斷 |
| EINVAL | semaphore 無效 | semaphore 或時間 tv_nsecs 無效 |
| EAGAIN | - | semaphore 為 0 | - |
| ETIMEDOUT | - | - | 逾時 |
註:uClibc 不支援 pshared 和 named semaphore,SEM_VALUE_MAX 是 2147483647。內部使用 __pthread_lock()、一個 semaphore 計數值、以及一個 waiting queue。
應用:binary semaphore (比較:mutex), counting semaphore
參考
- man sem_overview, man sem_init, man sem_wait