[英]Signals handling in C
我編寫了以下程序來學習SIG_SETMASK
的行為。
下面的程序應該阻塞SIGINT
中斷信號,直到func()
函數調用
sigprocmask(SIG_SETMASK,&fOnemask,NULL);
由於fOnemask為空,因為之前沒有信號存儲在sigset中。 但正如我所說
sigprocmask(SIG_SETMASK,&fTwoCmask,NULL);
返回之前在func2()
函數內部,其中fTwomask包含func()
函數創建的先前信號列表,程序開始接收信號,並且在傳遞SIGINT時中斷程序。
為什么會這樣呢?
void func();
void func2();
int main()
{
int childpid,child;
childpid=fork();
if(childpid==0)
{
func();
}
while(wait(NULL)>0);
return 0;
}
void func()
{
sigset_t sigmask,fOnemask;
sigemptyset(&sigmask);
sigaddset(&sigmask,SIGINT);
sigprocmask(SIG_SETMASK,&sigmask,&fOnemask);
func2();
int i;
for(i=0;i<10;i++)
{
sleep(1);
printf("%d\n",i);
}
sigprocmask(SIG_SETMASK,&omask,NULL);
printf("returning from func\n");
}
void func2()
{
sigset_t sigmask,fTwomask;
sigemptyset(&sigmask);
sigfillset(&sigmask);
sigprocmask(SIG_SETMASK,&sigmask,&fTwomask);
int i;
for(i=0;i<10;i++)
{
sleep(1);
printf("%d\n",i);
}
sigprocmask(SIG_SETMASK,&fTwomask,NULL);
printf("func2 ending\n");
}
父進程被SIGINT中斷,因為您從未在父進程中為SIGINT設置任何信號處理,因此將其設置為SIG_DFL(可能,除非您在外殼中啟用了中斷處理,這幾乎是不可能的),因此進程終止。
你是對的; 發送中斷時,shell不會死。 那是因為shell非常注意確保它們不會被中斷殺死。
對主要問題的評論之一是:
如果我在
main
函數的sigset_t
對象中添加信號,然后從main
調用foo()
。 然后,我在sigprocmask(SIG_SETMASK, &foomask, &oldmask)
foo()
等foo()
本地的另一個sigset_t
對象中添加一個信號。 當我調用sigprocmask(SIG_SETMASK, &oldset, NULL)
,sigprocmask(SIG_SETMASK, &oldset, NULL)
做什么?
您的評論(問題)充其量是令人困惑的; 注釋不是編輯問題的最佳方法。
據我了解,您在問:
static void foo(void);
int main(void)
{
sigset_t mainmask;
sigemptyset(&mainmask);
sigaddset(&mainmask, SIGINT);
// No call to sigprocmask() here...
foo();
return(0);
}
static void foo(void)
{
sigset_t foomask;
sigset_t oldmask;
sigset_t oldset; // Uninitialized
sigemptyset(&foomask);
sigaddset(&foomask, SIGQUIT); // Different signal
if (sigprocmask(SIG_SETMASK, &foomask, &oldmask) != 0)
...process error...
if (sigprocmask(SIG_SETMASK, &oldset, NULL) != 0)
...process error...
...other code, presumably...
}
這就是評論中寫的內容,據我所知。 而且由於oldset
初始化,因此您會遭受GIGO(垃圾進,垃圾出)的困擾; 沒有人可以說會發生什么,因為行為是不確定的。
如果您是在問題中使用oldmask
而不是oldset
,則foo()
可能看起來像:
static void foo(void)
{
sigset_t foomask;
sigset_t oldmask;
sigemptyset(&foomask);
sigaddset(&foomask, SIGQUIT); // Different signal
if (sigprocmask(SIG_SETMASK, &foomask, &oldmask) != 0)
...process error...
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) != 0)
...process error...
...other code, presumably...
}
然后,第二個sigprocmask()
撤消第一次調用sigprocmask()
所做的更改。 請記住,SIG_SETMASK選項的意思是“將過程信號掩碼設置為恰好第二個參數中的掩碼”(除非第二個參數為null,在這種情況下,第三個參數不應為null,並且第一個參數是什么都沒有關系參數,因為它變成了在不更改任何內容的情況下找出當前掩碼的調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.