2012-09-05 60 views
0

我必須編寫一個線程安全的庫,它使用POSIX信號量(用作具有初始值= 1的互斥量)進行同步。我發現一些問題來正確管理異步信號。我有一個應用程序鏈接到這個靜態庫和應用程序(多線程)調用庫函數。訪問一些內部結構是由POSIX信號控制(這是內部的庫):如何在多線程應用程序中用異步信號管理共享的POSIX信號量

void library_func1(lib_handler *h) 
{ 
    sem_wait(sem); 
    /* do some stuff with global data */ 
    sem_post(sem); 
} 

void library_func2(lib_handler *h) 
{ 
    sem_wait(sem); 
    /* do some stuff with global data */ 
    sem_post(sem); 
} 

void library_close(lib_handler *h) 
{ 
    ... 
} 

追加什麼,如果一個異步信號,讓我們說SIGINT,提高當一個線程鎖定該信號?如果我重新啓動應用程序,我會產生死鎖,因爲信號量存在,它的值是0。有一個函數library_close可以在異步信號提出時釋放信號量,但哪種方法是最好的方法來執行和檢查(我認爲只有在後面跟着exit,該函數纔會是信號安全的)?在多線程應用程序中,對於所有信號來說,通常都有一個單線程管理器的好習慣:這個線程應該在庫中或可以在應用程序中啓動它?

謝謝大家。

回答

-1

靜態庫的狀態不會在應用程序的不同運行之間傳遞,也不會由使用它的其他應用程序共享。它是使用它的應用程序狀態的一部分。所以你的信號量不會處於不穩定的狀態。

+0

信號量在應用程序之間共享。 – MirkoBanchi

+0

如何?你使用某種類型的進程間通信方案嗎? – insomniac2846

+0

POSIX信號量可通過例如'/ dev/shm'進行訪問,因此在進程間共享。 – MirkoBanchi

0

Linux futexes有同樣的問題。它不是完全可以解決的,但是你可以做的是寫入進程的pid,將信號量鎖定在同一個共享內存區域的某處。如果另一個進程試圖鎖定信號量並且它花費的時間太長(對於'太長'的某個值),它會通過從共享內存中讀取pid來找出鎖定了信號量的進程。如果該過程不再存在,那麼您知道自己處於死鎖狀態(因爲庫的內部數據可能處於不一致的狀態,您應該死掉)。

還有一場小規模的比賽,因爲鎖定的過程可能會在鎖定之後但在寫入其pid之前死亡。 AFAIK無法避免使用信號量。 (如果你有一個鎖定實現,其中pid是以自動方式寫入鎖定變量,但你可能需要自己寫這個。)