1. sigprocmask函式提供遮蔽和解除遮蔽訊號的功能。
從而實現關鍵**的執行不被打斷。
函式宣告如下:
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
其中引數 how可設定的引數為:sig_block, sig_unblock,sig_setmask
sig_block:
按照引數 set 提供的遮蔽字,遮蔽訊號。並將原訊號遮蔽儲存到oldset中。
sig_unblock:
按照引數 set 提供的遮蔽字進行訊號的解除遮蔽。針對set中的訊號進行解屏。
sig_setmask:
按照引數 set 提供的訊號設定重新設定系統訊號設定。
2. 訊號遮蔽與解屏常見實現
方法一: sig_block, sig_unblock成對實現
優點oldset可以不管。
方法二:
sig_block設定遮蔽,儲存原有訊號設定。
sig_setmask重新恢復原有設定。
3. 遮蔽過程中接受到的訊號如何處理
在訊號遮蔽過程中,出現的所有被遮蔽的訊號,不管發生多少次,在訊號解除遮蔽後,系統會執行一次被遮蔽訊號上的操作。
#include#include#includeint flag_sigusr1 = 0;int flag_sigusr2 = 0;
void sig_usr1(int signo)
void sig_usr2(int signo)
int main(void)
sleep(5);
}fprintf(stdout, "first while was broken\n");
//重新設定為0
flag_sigusr1 = 0;
flag_sigusr2 = 0;
// block sigusr1
sigemptyset(&newmask);
sigaddset(&newmask, sigusr1);
if(sigprocmask(sig_block, &newmask, &oldmask) < 0)
fprintf(stdout, "only catch sigusr2 can break, because sigusr1 has been blocked\n");
while(1)
sleep(5);
}fprintf(stdout, "second while was broken\n");
fprintf(stdout, "after second while was broken, flag_sigusr1=%d, flag_sigusr2=%d\n", flag_sigusr1, flag_sigusr2);
return 0;
}
多執行緒情況下每個執行緒共用訊號處理函式,但是每個執行緒可以選擇自己是否block某個訊號。
再看乙個多執行緒的例子:子執行緒的功能同上,主線程接收到hup訊號會向子執行緒傳送usr2訊號。
#include#include#include#includeint flag_sigusr1 = 0;int flag_sigusr2 = 0;
int flag_sighup = 0;
void sig_usr1(int signo)
void sig_usr2(int signo)
void sig_hup(int signo)
void *thread_control_signal(void *arg)
fprintf(stdout, "thread|first while. catch sigusr1 or sigusr2 can break\n");
while(1)
sleep(5);
}flag_sigusr1 = 0;
//thread block sigusr1
sigaddset(&newmask, sigusr1);
if(pthread_sigmask(sig_block, &newmask, &oldmask) < 0)
fprintf(stdout, "thread|first while. catch sigusr2 can break\n");
while(1)
sleep(10);
}fprintf(stdout, "thread|thread exit\n");
return (void *)0;
}int main()
//main thread block sigusr1
sigemptyset(&newmask);
sigaddset(&newmask, sigusr1);
if(pthread_sigmask(sig_block, &newmask, null) < 0)
//main thread wait sighup
sigemptyset(&newmask);
sigaddset(&newmask, sighup);
if(sigwait(&newmask, &signo) < 0)
fprintf(stdout, "main|get sighup\n");
pthread_kill(tid, sigusr2);
pthread_kill(tid, sigusr2);
pthread_join(tid, null);
fprintf(stdout, "main|exit\n");
return 0;
}
kill函式向程序傳送訊號,pthread_kill用於向執行緒傳送訊號。
阻塞訊號及訊號遮蔽pending
1.訊號在核心中的三種表示 1 訊號遞達 實際執行訊號的處理動作 2 訊號未決 pending 訊號從產生到遞達的狀態,是一種記錄狀態 3 阻塞訊號 block 被阻塞的訊號不會遞達,它在產生時處於未決狀態,直到程序解除對這個訊號的阻塞,才會執行遞達,但不會立即遞達 阻塞與忽略的不同 忽略是在訊號遞...
linux訊號集與訊號遮蔽字
訊號傳遞過程 一些名詞 需要注意的是 這些變數之間也存在一些關係,比如 程序將訊號遮蔽字的2號為置為1,也就是說遮蔽sigint訊號,那麼但你向程序傳送該訊號時 ctrl c 該訊號必然處於未決狀態。那麼,訊號未決狀態字的2號位自然也就是1啦。訊號集操作函式 posix.1 定義了乙個資料型別sig...
linux 訊號遮蔽
include include include include include include sigemptyset newmask 獲取空遮蔽訊號集 sigfillset newmask 獲取遮蔽了所有訊號的遮蔽訊號集,除了那兩個sigkill sigstop sigpending pendma...