關於非同步訊號安全

nkbai發表於2016-01-13

關於非同步訊號安全

執行緒安全與重入以及非同步訊號安全的區別.

可重入一定是執行緒安全的,但是執行緒安全不一定是可重入的.

引用別人的部落格中的話吧.如下:

http://blog.csdn.net/xiaofei0859/article/details/5818511

 執行緒安全:
      
執行緒安全函式:在C語言中區域性變數是在棧中分配的,任何未使用靜態資料或其他共享資源的函式都是執行緒安全的。
                    
使用全域性變數的函式是非執行緒安全的。
                    
使用靜態資料或其他共享資源的函式,必須通過加鎖的方式來使函式實現執行緒安全。

       執行緒安全的(Thread-Safe)
                  
如果一個函式在同一時刻可以被多個執行緒安全地呼叫,就稱該函式是執行緒安全的。
                  
執行緒安全函式解決多個執行緒呼叫函式時訪問共享資源的衝突問題。

       可重入(Reentrant)
                  
函式可以由多於一個執行緒併發使用,而不必擔心資料錯誤。可重入函式可以在任意時刻被中斷,稍後再繼續執行,不會丟失資料。可重  入性解決函式執行結果的確定性和可重複性。


可重入函式編寫規範為:

1、不在函式內部使用靜態或全域性資料 
2
、不返回靜態或全域性資料,所有資料都由函式的呼叫者提供。 
3
、使用本地資料,或者通過製作全域性資料的本地拷貝來保護全域性資料。
4
、如果必須訪問全域性變數,利用互斥機制來保護全域性變數。
5
、不呼叫不可重入函式。

兩者之間的關係:
1
、一個函式對於多個執行緒是可重入的,則這個函式是執行緒安全的。
2
、一個函式是執行緒安全的,但並不一定是可重入的。【使用互斥鎖實現的執行緒安全】
3
、可重入性要強於執行緒安全性。

具體看程式碼,這裡的thread_safe_not_reentrant就是一個例子,請忽略printf除錯函式,我沒有查這個函式的重入特性。

請在執行以後按下ctrl c,觀察程式死鎖。

 

#include <stdio.h>		/* for convenience */
#include <stdlib.h>		/* for convenience */
#include <unistd.h>		/* for convenience */
#include <signal.h>		/* for SIG_ERR */
#include <pthread.h>

pthread_mutex_t env_mutex;
void thread_safe_not_reentrant(char *name){
    printf("call from %s
",name);
    pthread_mutex_lock(&env_mutex);
    sleep(5);
    pthread_mutex_unlock(&env_mutex);
    printf("return from %s
",name);
}
static void
sig_int(int signo)
{
    printf("caught SIGINT
");
    thread_safe_not_reentrant("sig int ");
}



int
main(void)
{
    //if default mutex ,it use recursive , will not deadlock
    //env_mutex=PTHREAD_MUTEX_INITIALIZER;
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_NORMAL);
    pthread_mutex_init(&env_mutex,&attr);
    pthread_mutexattr_destroy(&attr);
    if (signal(SIGINT, sig_int) == SIG_ERR)
        printf("signal(SIGINT) error");
    thread_safe_not_reentrant("main");
    return 0;
}

  


相關文章