日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux进程中对信号的屏蔽,linux进程中的信号屏蔽

發布時間:2024/9/30 linux 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux进程中对信号的屏蔽,linux进程中的信号屏蔽 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在linux的進程中可以接收到各種的信號,并且如果你不對信號進行處理,linux中的進程就會采用默認的處理方式處理,比如ctrl-c的信號,進程對它的處理就是終止進程的執行。

在linux中,我們也可以在進程中屏蔽掉某些信號,使進程不去處理這些信號,但其中的SIGKILL和SIGSTOP是不能被阻塞的。

在這里先介紹幾個信號的函數:

int sigempty(sigset_t *set);???????????????? // 清空信號集set

int sigfillset(sigset_t *set);?????????????????? // 填滿信號集,即讓set包含所有的信號

int sigaddset(sigset_t *set, int signo);? // 在set中增加signo信號

int sigdelset(sigset_t *set, int signo);?? // 在set中去掉signo信號

int sigismember(sigset_t *set, int signo); // 信號signo是否在信號集set中

int sigprocmask(int how, const sigset_t set, sigset_t oset); // 若oset非空,則進程的當前信號屏蔽字通過oset返回,若set是一個非空指針,著參數how指示如何修改當前信號的屏蔽字,how可以取三個值:

SIG_BLOCK:增加一個信號。

SIG_UNBLOCK:解除一個信號。

SIG_SETMASK:該進程的信號將被set信號集取代。

int sigpengding(sigset_t *set);? // 該函數返回信號集,該信號通過set參數返回。

以上函數都在#include 頭文件中。

下面用《unix環境高級編程》里的一個例子說明一下,代碼有所修改,先看代碼(main.c,里面有個人對代碼的注釋):

view plaincopy to clipboardprint?

#include

#include

#include

static void sig_quit(int);

int

main(void)

{

sigset_t newmask, oldmask, pendingmask;

//設置對信號SIGQUIT的處理函數

if (signal(SIGQUIT, sig_quit) == SIG_ERR)

{

fprintf(stderr, "can't catch SIGQUIT/n");

exit(1);

}

//設置一個空的信號集

sigemptyset(&newmask);

sigaddset(&newmask, SIGQUIT); // 在這個信號集中增加SIGQUIT信號

//在當前進程中增加newmask信號集作為屏蔽信號集,oldmask返回當前進程的信號集

if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)

{

fprintf(stderr, "SIG_BLOCK error/n");

exit(1);

}

sleep(5);

//返回當前進程信號集

if (sigpending(&pendingmask) < 0)

{

fprintf(stderr, "sigpending error/n");

exit(1);

}

//檢查SIGQUIT信號是否在當前信號集中

if (sigismember(&pendingmask, SIGQUIT))

printf("/nSIGQUIT pending/n");

//恢復進程的信號集

if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)

{

fprintf(stderr, "SIG_SETMASK error/n");

exit(1);

}

printf("SIGQUIT unblocked/n");

sleep(5);

exit(0);

}

static void sig_quit(int signo)

{

printf("caught SIGQUIT/n");

//恢復進程對SIGQUIT的默認處理

if (signal(SIGQUIT, SIG_DFL) == SIG_ERR)

{

fprintf(stderr, "can't reset SIGQUIT/n");

exit(0);

}

}

#include

#include

#include

static void sig_quit(int);

int

main(void)

{

sigset_t newmask, oldmask, pendingmask;

//設置對信號SIGQUIT的處理函數

if (signal(SIGQUIT, sig_quit) == SIG_ERR)

{

fprintf(stderr, "can't catch SIGQUIT/n");

exit(1);

}

//設置一個空的信號集

sigemptyset(&newmask);

sigaddset(&newmask, SIGQUIT); // 在這個信號集中增加SIGQUIT信號

//在當前進程中增加newmask信號集作為屏蔽信號集,oldmask返回當前進程的信號集

if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)

{

fprintf(stderr, "SIG_BLOCK error/n");

exit(1);

}

sleep(5);

//返回當前進程信號集

if (sigpending(&pendingmask) < 0)

{

fprintf(stderr, "sigpending error/n");

exit(1);

}

//檢查SIGQUIT信號是否在當前信號集中

if (sigismember(&pendingmask, SIGQUIT))

printf("/nSIGQUIT pending/n");

//恢復進程的信號集

if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)

{

fprintf(stderr, "SIG_SETMASK error/n");

exit(1);

}

printf("SIGQUIT unblocked/n");

sleep(5);

exit(0);

}

static void sig_quit(int signo)

{

printf("caught SIGQUIT/n");

//恢復進程對SIGQUIT的默認處理

if (signal(SIGQUIT, SIG_DFL) == SIG_ERR)

{

fprintf(stderr, "can't reset SIGQUIT/n");

exit(0);

}

}

編譯: gcc main.c

生成:a.out

運行:./a.out

輸出如下(ubuntu9.10):

^/

SIGQUIT pending

caught SIGQUIT

SIGQUIT unblocked

^/退出

下面解釋一下輸出:

^/??????????????????????????????? 在第一次sleep(5)的5秒中內產生信號一次(按ctrl+/)

SIGQUIT pending????????? 從sleep返回后

caught SIGQUIT?????????? 在信號處理函數中

SIGQUIT unblocked?????? 從sigprocmask返回后

^/退出????????????????????????? 再次產生信號

我們對著程序來看下輸出。

在我們設置SIGQUIT屏蔽字和恢復進程的信號集這段時間,我們產生的SIGQUIT信號,我們的進程并沒去處理,所以輸出了SIGQUIT pending 。

在我們恢復進程的信號集后,我們進程就撲捉到了我們剛才產生的信號,因而就輸出了caught SIGQUIT,在sig_quit函數中,我們恢復了SIGQUIT的默認處理方式(即終止進程運行),進程當我們再次產生SIGQUIT信號,進程就退出了。

當我們產生進程時,一些unix系統會對進程中要處理的信號進行排隊,我們的進程會對信號隊列中的信號進行處理。我們再運行一下剛才的程序,在第一次sleep(5)的5秒中內產生信號10次信號,看下會怎么樣,下面是我的輸出:

^/^/^/^/^/^/^/^/^/^/

SIGQUIT pending

caught SIGQUIT

SIGQUIT unblocked

^/退出

下面解釋一下輸出:

^/^/^/^/^/^/^/^/^/^/?? 在第一次sleep(5)的5秒中內產生信號10次信號

SIGQUIT pending?????????????? 從sleep返回后

caught SIGQUIT??????????????? 從sigprocmask返回后

SIGQUIT unblocked?????????? 從sigprocmask返回后

^/退出????????????????????????????? 再次產生信號

這里可以看到linux系統對沒有對信號進行排隊,產生10次信號,只處理一次。

在上面的例子中,我們用signal函數來指定信號的處理函數,用sigprocmask來指定信號屏蔽字,其實這些都可以在一個函數中解決,它就是sigaction ,推薦使用sigaction函數。

pthread_sigmask與sigprocmask。前者是線程安全的。

pthread_sigmask改變的是線程的信號集與整個進程無關。

總結

以上是生活随笔為你收集整理的linux进程中对信号的屏蔽,linux进程中的信号屏蔽的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。