關于異步信號安全

發表于:2007-05-25來源:作者:點擊數: 標簽:安全引出我對信號異步
引出我對這個東西重視的原因是sun的文檔指出,在使用單線程復制模型fork1()或者posix標準的fork()時,在子進程中調用exec之前不要做任何操作,如果一定要做,盡量不要調用任何庫函數,要做異步信號 安全 的操作; sun的文檔對異步信號安全函數如下描述: 可
引出我對這個東西重視的原因是sun的文檔指出,在使用單線程復制模型fork1()或者posix標準的fork()時,在子進程中調用exec之前不要做任何操作,如果一定要做,盡量不要調用任何庫函數,要做異步信號安全的操作;

sun的文檔對異步信號安全函數如下描述:

clearcase/" target="_blank" >cccccc">可以被信號控制器安全調用的函數被稱為異步信號安全函數。POSIX標準定義并 詳列了異步信號安全函數(IEEE Std 1003.1-1990.3.3.1.3(3)(f), page 55)。除 了POSIX異步信號安全函數外,下列三個函數也是異步安全的。
· sema_post(3T)
· thr_sigsetmask(3T)
· thr_kill(3T)

那份posix文檔我沒有找到,估計是過于古老;

但是需要安全的原因是和多線程的安全類似,關于共享資源的爭用和死鎖;

最基本的例子還是printf();

我的進程正在printf中,這時候被中斷了,中斷處理函數中使用了printf,

這樣,麻煩就來了;為什么呢;

因為剛才正在進行的那個printf鎖定了資源,信號處理函數中的這個printf就會被阻塞在那個鎖上面,

而且可悲的是永遠也沒有人能去把那個鎖給打開。55555555

所以在信號處理器中不要使用對共享資源加鎖的玩藝;

 

那么為什么單線程復制模型的fork也要求這種安全呢;

這種類型的函數在solaris線程庫中叫做fork1(2); 在posix線程庫中是fork(2);

他們在拷貝父進程的映像的時候僅僅拷貝調用fork函數的這個線程,其他的線程都被丟棄了;好慘。

還是拿printf;我的父進程中有一個線程正在printf();

這時候有一個線程進行了一次單線程復制模型的fork,于是它復制了一份自己,但同時它也復制了整個進程中的資源,包括那個正在被printf鎖定的鎖;麻煩又來了;

如果這個新的進程用遠不去碰那個鎖的話,就不會有事;但如果他多事,一定要去printf;

完蛋了,那個鎖是鎖住的,而且在這個進程里面并沒有那個上鎖的線程存在,也就是說,沒有誰會來解開這個鎖;

我等啊,我望穿了雙眼,等到天荒地老,等到??菔癄€;

 

大多數情況下,不會出現這種情況;那是因為這種類型的fork函數我們調用的目的就是在子進程里面調用exec();

而且絕大部分情況是fork()之后立即調用exec();所以沒問題;如果想多做些事情,就要小心了;

solaris線程庫fork(2);是多線程復制模型的,他會把整個進程中的所有線程一起復制,也就沒那個問題了;posix線程庫中沒有相應的函數;

但是posix線程庫提供了另一種接口 pthread_atfork(3T);這個函數要做三件工作,就是在fork之間將所有的鎖鎖住,在子進程中和父進程中分別在把鎖全都打開,也就解決了那個問題;

好像扯得有些遠,本來說信號安全的,結果扯上了fork();唉,反正被來就是從fork扯出來的;

原文轉自:http://www.anti-gravitydesign.com

評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97