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_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。
- 可用來在特定時間執行某項工作。
- 等候是呼叫 nanosleep() 處理
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
- kernel 裡的 semaphore (LDD3 ch5.3)
- System V semaphore:semget(), semop(), semctl() [比較:Implement POSIX Semaphore APIs using System V Semaphores APIs]
沒有留言:
張貼留言