1. 程式人生 > >關於訊號量sem_wait的整理(轉)

關於訊號量sem_wait的整理(轉)

SYNOPSIS
       #include <semaphore.h>

       int sem_init(sem_t *sem, int pshared, unsigned int value);
//初始化訊號量
       int sem_wait(sem_t * sem);
//等待訊號,獲取擁有權
       int sem_trywait(sem_t * sem);

       int sem_post(sem_t * sem);
//發出訊號即釋放擁有權
       int sem_getvalue(sem_t * sem, int * sval);

       int sem_destroy(sem_t * sem);
//登出訊號量,在linux中其本質是沒有任何作用的,它不做任何事情。
DESCRIPTION
       This manual page documents POSIX 1003.1b semaphores, not to be confused with SystemV semaphores as described in ipc(5),
       semctl(2) and semop(2).

       Semaphores are counters for resources shared between threads. The basic operations on semaphores are: increment the
       counter atomically, and wait until the counter is non-null and decrement it atomically.
//訊號量是在多執行緒環境中共享資源的計數器。對訊號量的基本操作無非有三個:對訊號量的增加;然後阻塞執行緒等待,直到訊號量不為空才返回;然後就是對訊號量的減少。
// 在程式設計中,訊號量最常用的方式就是一個執行緒A使用sem_wait阻塞,因為此時訊號量計數為0,直到另外一個執行緒B發出訊號post後,訊號量計數加 1,此時,執行緒A得到了訊號,訊號量的計數為1不為空,所以就從sem_wait返回了,然後訊號量的計數又減1變為零。
       sem_init initializes the semaphore object pointed to by sem. The count associated with the semaphore is set initially to
       value. The pshared argument indicates whether the semaphore is local to the current process ( pshared is zero) or is to
       be shared between several processes ( pshared is not zero). LinuxThreads currently does not support process-shared
       semaphores, thus sem_init always returns with error ENOSYS if pshared is not zero.
//在使用訊號量之前,我們必須初始化訊號。第三個引數通常設定為零,初始化訊號的計數為0,這樣第一次使用sem_wait的時候會因為訊號計數為0而等待,直到在其他地方訊號量post了才返回。除非你明白你在幹什麼,否則不要將第三個引數設定為大於0的數。
//第二個引數是用在程序之間的資料共享標誌,如果僅僅使用在當前程序中,設定為0。如果要在多個程序之間使用該訊號,設定為非零。但是在Linux執行緒中,暫時還不支援程序之間的訊號共享,所以第二個引數說了半天等於白說,必須設定為0.否則將返回ENOSYS錯誤。
       sem_wait suspends the calling thread until the semaphore pointed to by sem has non-zero count. It then atomically
       decreases the semaphore count.
//當訊號的計數為零的時候,sem_wait將休眠掛起當前呼叫執行緒,直到訊號量計數不為零。在sem_wait返回後訊號量計數將自動減1.

       sem_trywait is a non-blocking variant of sem_wait. If the semaphore pointed to by sem has non-zero count, the count is
       atomically decreased and sem_trywait immediately returns 0. If the semaphore count is zero, sem_trywait immediately
       returns with error EAGAIN.
//sem_trywait是一個立即返回函式,不會因為任何事情阻塞。根據其返回值得到不同的資訊。如果返回值為0,說明訊號量在該函式呼叫之前大於0,但是呼叫之後會被該函式自動減1.至於呼叫之後是否為零則不得而知了。如果返回值為EAGAIN說明訊號量計數為0。
       sem_post atomically increases the count of the semaphore pointed to by sem. This function never blocks and can safely be
       used in asynchronous signal handlers.
//解除訊號量等待限制。讓訊號量計數加1.該函式會立即返回不等待。
       sem_getvalue stores in the location pointed to by sval the current count of the semaphore sem.
//獲得當前訊號量計數的值。
       sem_destroy destroys a semaphore object, freeing the resources it might hold. No threads should be waiting on the
       semaphore at the time sem_destroy is called. In the LinuxThreads implementation, no resources are associated with
       semaphore objects, thus sem_destroy actually does nothing except checking that no thread is waiting on the semaphore.
// 銷燬訊號量物件,釋放訊號量內部資源。然而在linux的執行緒中,其實是沒有任何資源關聯到訊號量物件需要釋放的,因此在linux中,銷燬訊號量物件的 作用僅僅是測試是否有執行緒因為該訊號量在等待。如果函式返回0說明沒有,正常登出訊號量,如果返回EBUSY,說明還有執行緒正在等待該訊號量的訊號。

CANCELLATION
       sem_wait is a cancellation point.

ASYNC-SIGNAL SAFETY
       On processors supporting atomic compare-and-swap (Intel 486, Pentium and later, Alpha, PowerPC, MIPS II, Motorola 68k),
       the sem_post function is async-signal safe and can therefore be called from signal handlers. This is the only thread syn-
       chronization function provided by POSIX threads that is async-signal safe.

       On the Intel 386 and the Sparc, the current LinuxThreads implementation of sem_post is not async-signal safe by lack of
       the required atomic operations.
//現在sem_post被POSIX所規範,當它改變訊號量計數器值的時候是執行緒安全的。

RETURN VALUE
       The sem_wait and sem_getvalue functions always return 0. All other semaphore functions return 0 on success and -1 on
       error, in addition to writing an error code in errno.
//通常返回值往往都為0,表示成功,如果有誤將返回-1,並且將錯誤的程式碼號賦值給errno。

ERRORS
       The sem_init function sets errno to the following codes on error:
//sem_init失敗時,常見錯誤有:
              EINVAL value exceeds the maximal counter value SEM_VALUE_MAX
   //第三個引數value值超過了系統能夠承受的最大值SEM_VALUE_MAX.

              ENOSYS pshared is not zero
   //你將第二引數設定為了非零,如果是linux系統,請將第二個引數設定為零

       The sem_trywait function sets errno to the following error code on error:

              EAGAIN the semaphore count is currently 0

       The sem_post function sets errno to the following error code on error:

              ERANGE after incrementation, the semaphore value would exceed SEM_VALUE_MAX (the semaphore count is left unchanged
                     in this case)
   //訊號量的計數超過了系統能夠承受的最大值SEM_VALUE_MAX。

       The sem_destroy function sets errno to the following error code on error:

              EBUSY some threads are currently blocked waiting on the semaphore.
   //某些執行緒正在使用該訊號量等待。

其實執行緒臨界區可以使用訊號量來實現,將訊號量的訊號初始化為1,然後在臨界區使用完畢後再置訊號量為1我們就可以輕鬆實現mutex了。

具體實現,自己慢慢琢磨一下吧。