linux中信号的处理,linux中关于信号处理笔记(二)
2 等待一個(gè)全局變量被設(shè)置
這種情況是等待一個(gè)信號(hào)處理程序設(shè)置一個(gè)全局變量。下面的例子用于捕捉中斷信號(hào)和退出信號(hào),但是希望僅當(dāng)退出信號(hào)處理程序時(shí),才喚醒主進(jìn)程。
#include
#include
#include
volatile sig_atomic_t quitflag;
/*
當(dāng)把聲明為該類型會(huì)保證該變量在使用或賦值時(shí), 無(wú)論是在32位還是64位的機(jī)器上都能保證操作是原子的, 它會(huì)根據(jù)機(jī)器的類型自動(dòng)適應(yīng)。這個(gè)類型是定義在signal.h文件中。*/
static void sig_int(int signo)
{
if(signo == SIGINT)
printf("\ninterrupt\n");
else if(signo == SIGQUIT)
quitflag = 1;//等待這個(gè)全局變量
}
int main(void)
{
sigset_t newmask, oldmask, zeromask;
if(signal(SIGINT, sig_int) == SIG_ERR)
{
printf("signal(SIGINT) error");
exit(1);
}
if(signal(SIGQUIT, sig_int) == SIG_ERR)
{
printf("signal(SIGQUIT) error");
exit(1);
}
sigemptyset(&zeromask);
sigemptyset(&newmask);
sigaddset(&newmask, SIGQUIT);
if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)//屏蔽SIGQUIT信號(hào)
{
printf("SIG_BLOCK error");
exit(1);
}
while(quitflag == 0)
{
sigsuspend(&zeromask);//sigsuspend解開(kāi)所有屏蔽信號(hào),然后等待quitflag變成1,然后才往下執(zhí)行,否則在這里循環(huán)
printf("quitflag = %d\n", quitflag);
}
quitflag = 0;
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
{
printf("SIG_SETMASK error");
exit(1);
}
exit(0);
}
由顯示結(jié)果可以看出,sigsuspend放開(kāi)屏蔽信號(hào),按下“ctrl+C”,進(jìn)入中斷,但是不設(shè)置quitflag,直到按下“ctrl+\”,quitflag置1,才往下執(zhí)行。
在單進(jìn)程程序當(dāng)中,主進(jìn)程和中斷共享變量,這不失為一種好辦法。
3 父子進(jìn)程通信,關(guān)于這個(gè)只有幾個(gè)函數(shù)。在此不做記錄。
另外重點(diǎn)說(shuō)下sigaction函數(shù):
int sigaction(int signo, const struct sigaction *restrict act, struct *restrictoact);
這個(gè)函數(shù)用來(lái)修改或者檢查與指定信號(hào)相關(guān)聯(lián)的處理動(dòng)作,其中,參數(shù)signo是要檢測(cè)或者修改其具體動(dòng)作的信號(hào)編號(hào),若act指針?lè)强?#xff0c;
則要修改其動(dòng)作,若oact非空,則系統(tǒng)由oact指針?lè)祷卦撔盘?hào)的上一個(gè)動(dòng)作。其中的結(jié)構(gòu)體如下:
struct sigaction{
void (*sa_handler)(int);
sigset_t sa_mask;
int sa_flag;
void (*sa_sigaction)(int, siginfo_t *, void *);
};
關(guān)于這個(gè)函數(shù)可以這樣理解:如果sa_handler字段有效,即這個(gè)字段是一個(gè)有效信號(hào)捕捉地址,則sa_mask字段信號(hào)集是這樣的
在調(diào)用該捕捉函數(shù)前,這一信號(hào)集要加到進(jìn)程的信號(hào)屏蔽字中,僅當(dāng)從信號(hào)捕捉函數(shù)返回時(shí)再將進(jìn)程的信號(hào)屏蔽字恢復(fù)到原來(lái)狀態(tài)
這樣,在信號(hào)處理函數(shù)調(diào)用時(shí),就能阻塞某些信號(hào),即在執(zhí)行信號(hào)處理程序時(shí),系統(tǒng)新建立的信號(hào)能被屏蔽,保證了在信號(hào)處理過(guò)程當(dāng)中,
如果同一種信號(hào)再次發(fā)生,那么它會(huì)被阻塞到前一個(gè)新紅處理完畢。例如:
int main(void)
{
int i = 0;
structsigactionact, oldact;
act.sa_handler = show_handler;
...
sigaddset(&act.sa_mask, SIGQUIT);
....
sigaction(SIGINT, &act, &oldact);
while(1) {
sleep(1);
printf("sleeping %d\n", i);
i++;
}}
上面函數(shù)設(shè)置SIGINT捕捉函數(shù),在從SIGINT信號(hào)處理函數(shù)返回以前,把SIGQUIT信號(hào)屏蔽,從信號(hào)處理函數(shù)返回以后,恢復(fù)原來(lái)的信號(hào)屏蔽字。
這樣即使在信號(hào)處理過(guò)程當(dāng)中產(chǎn)生SIGQUIT信號(hào),在接觸屏蔽以后,信號(hào)SIGQUIT也能遞達(dá)而不丟失。
總結(jié)
以上是生活随笔為你收集整理的linux中信号的处理,linux中关于信号处理笔记(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux monitor模式,ubun
- 下一篇: linux安装字体后wps无法打开,Ub