我正在通過使用sigaction. 在做我自己的練習時,我試圖先阻止信號(SIGINT 和 SIGQUIT),然后再解除對它們的阻止。
在我的終端輸出中,在信號被阻塞的 for 回圈中,如果我嘗試按 Ctrl C 或 Ctrl ,它仍然會列印出如下陳述句,但是在解除阻塞后,它不會列印出內容在第二個 for 回圈中。
(block) working ....
(block) working ....
^C(block) working ....
(block) working ....
^\(block) working ....
The work is done, now you can ...
但是,如果我在第一個 for 回圈中的程式執行期間沒有嘗試按 Ctrl C 或 Ctrl \,那么第二個 for 回圈將被列印出來。
(block) working ....
(block) working ....
(block) working ....
(block) working ....
(block) working ....
The work is done, now you can ...
(unblock) working ....
(unblock) working ....
(unblock) working ....
(unblock) working ....
(unblock) working ....
我希望達到的預期結果如下:
(block) working ....
(block) working ....
^C(block) working ....
(block) working ....
^\(block) working ....
The work is done, now you can ...
(unblock) working ....
^C
其中我可以嘗試在第一個 for 回圈期間多次按下 Ctrl C 或 Ctrl \,然后在進入第二個 for 回圈時按下任一信號將終止命令。
這是我的代碼:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
int i;
sigset_t sigs, sigs2;
sigemptyset(&sigs);
sigaddset(&sigs, SIGINT);
sigaddset(&sigs, SIGQUIT);
sigprocmask(SIG_SETMASK, &sigs, NULL); // tried with SIGBLOCK, same issues
for (i=0; i<5; i)
{
printf("(block) working ....\n");
sleep (1);
}
printf("The work is done, now you can ...\n");
// unblock signals
sigprocmask(SIG_UNBLOCK, &sigs, NULL);
for (int j=0; j<5; j)
{
printf("(unblock) working ....\n");
sleep (1);
}
exit(0);
}
提前感謝任何見解。
uj5u.com熱心網友回復:
阻止信號與忽略信號不同。如果一個信號被發送到一個行程,而該信號被該行程阻塞,那么它會保持掛起狀態,直到信號被解除阻塞或行程終止。
這正是你觀察到的。當它們被阻塞時,您將 aSIGINT和 a傳遞SIGQUIT給您的流程。一個在它們被解除阻塞后立即交付,在進入第二個回圈之前終止行程。
實際交付的是哪個(第一個)是未指定的,但是如果一個處理程式注冊了,因此它不會終止行程,那么這兩個處理程式都可能被交付,甚至第一個接收到的處理程式也可能被交付被第二個收到打斷。
但是,多個相同的常規信號不會排隊。例如,無論SIGQUIT您在該信號被阻塞時發送了多少s,當該信號被解除阻塞時,等待傳遞的不會超過一個。
uj5u.com熱心網友回復:
添加到 John Bollinger 的答案中,正如他所建議的那樣,您在這里要做的是忽略信號,而不僅僅是阻止它們。您可以使用sigaction此,設定處理程式SIGINT,并SIGQUIT以SIG_IGN(忽略),然后設定回SIG_DFL(默認處理程式)。
這是一個簡單的例子:
#define _POSIX_C_SOURCE 1
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
int main(void) {
int i;
struct sigaction sa = { .sa_handler = SIG_IGN };
if (sigaction(SIGINT, &sa, NULL) == -1) {
perror("sigaction(SIGINT, SIG_IGN) failed");
return 1;
}
if (sigaction(SIGQUIT, &sa, NULL) == -1) {
perror("sigaction(SIGQUIT, SIG_IGN) failed");
return 1;
}
for (i = 0; i < 5; i) {
printf("(ignore) working ....\n");
sleep(1);
}
printf("The work is done, now you can ...\n");
sa.sa_handler = SIG_DFL;
if (sigaction(SIGINT, &sa, NULL) == -1) {
perror("sigaction(SIGINT, SIG_DFL) failed");
return 1;
}
if (sigaction(SIGQUIT, &sa, NULL) == -1) {
perror("sigaction(SIGQUIT, SIG_DFL) failed");
return 1;
}
for (i = 0; i < 5; i) {
printf("(un-ignore) working ....\n");
sleep(1);
}
return 0;
}
上面的例子是微不足道的,但請注意,在一般情況下,您應該使用 的第三個引數sigaction來保存struct sigaction您正在修改的信號的電流,以便您以后可以將其恢復而不是將其重置為SIG_DFL。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/341519.html
