linux進程---信號處理函數

前言:

Linux下對信號(SIGNAL)的操作函數有很多。總結了一下,常用的大概有以下幾個:

alarm,kill,pause,sigaction,sigaddset,sigdelset,sigemptyset,

sigfillset,sigismember,signal,sigpending,sigprocmask,sleep

詳細說明:(部分資料引用互聯網)

1.alarm(設置信號傳送鬧鐘)
相關函數 signal,sleep,
表頭文件 #include<unistd.h>

定義函數 unsigned int alarm(unsigned int seconds);

函數說明 alarm()用來設置信號SIGALRM在經過參數seconds指定的秒數後傳送給目前的進程。如果參數seconds 爲0,則之前設置的鬧鐘會被取消,並將剩下的時間返回。返回值返回之前鬧鐘的剩餘秒數,如果之前未設鬧鐘則返回0。

範例 

#include<unistd.h>
#include<signal.h>
void handler()
{

       printf("hello\n");
}
main()
{
      int i;
      signal(SIGALRM,handler);
      alarm(5);
      for(i=1;i<7;i++){
      printf("sleep %d ...\n",i);
      sleep(1);
      }
}

執行 sleep 1 ...
sleep 2 ...
sleep 3 ...
sleep 4 ...
sleep 5 ...
hello
sleep 6 ...

2.kill(傳送信號給指定的進程)
相關函數 raise,signal

表頭文件 #include<sys/types.h>
#include<signal.h>

定義函數 int kill(pid_t pid,int sig);

函數說明 kill()可以用來送參數sig指定的信號給參數pid指定的進程。參數pid有幾種情況:
pid>0 將信號傳給進程識別碼爲pid 的進程。
pid=0 將信號傳給和目前進程相同進程組的所有進程
pid=-1 將信號廣播傳送給系統內所有的進程
pid<0 將信號傳給進程組識別碼爲pid絕對值的所有進程
參數sig代表的信號編號可參考附錄D

返回值 執行成功則返回0,如果有錯誤則返回-1。

錯誤代碼 EINVAL 參數sig 不合法
ESRCH 參數pid 所指定的進程或進程組不存在
EPERM 權限不夠無法傳送信號給指定進程

範例 #include<unistd.h>
#include<signal.h>
#include<sys/types.h>
#include<sys/wait.h>
main()
{
pid_t pid;
int status;
if(!(pid= fork())){
printf("Hi I am child process!\n");
sleep(10);
return;
}
else{
printf("send signal to child process (%d) \n",pid);
sleep(1);
kill(pid ,SIGABRT);
wait(&status);
if(WIFSIGNALED(status))
printf("chile process receive signal %d\n",WTERMSIG(status));
}
}

執行 sen signal to child process(3170)
Hi I am child process!
child process receive signal 6

3.pause(讓進程暫停直到信號出現)

相關函數 kill,signal,sleep

表頭文件 #include<unistd.h>

定義函數 int pause(void);

函數說明 pause()會令目前的進程暫停(進入睡眠狀態),直到被信號(signal)所中斷。

返回值 只返回-1。

錯誤代碼 EINTR 有信號到達中斷了此函數。

4.sigaction(查詢或設置信號處理方式)

相關函數 signal,sigprocmask,sigpending,sigsuspend

表頭文件 #include<signal.h>

定義函數 int sigaction(int signum,const struct sigaction *act ,struct sigaction *oldact);

函數說明 sigaction()會依參數signum指定的信號編號來設置該信號的處理函數。參數signum可以指定SIGKILL和SIGSTOP以外的所有信號。
如參數結構sigaction定義如下
struct sigaction
{
void (*sa_handler) (int);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer) (void);
}
sa_handler此參數和signal()的參數handler相同,代表新的信號處理函數,其他意義請參考signal()。
sa_mask 用來設置在處理該信號時暫時將sa_mask 指定的信號擱置。
sa_restorer 此參數沒有使用。
sa_flags 用來設置信號處理的其他相關操作,下列的數值可用。
OR 運算(|)組合
A_NOCLDSTOP : 如果參數signum爲SIGCHLD,則當子進程暫停時並不會通知父進程
SA_ONESHOT/SA_RESETHAND:當調用新的信號處理函數前,將此信號處理方式改爲系統預設的方式。
SA_RESTART:被信號中斷的系統調用會自行重啓
SA_NOMASK/SA_NODEFER:在處理此信號未結束前不理會此信號的再次到來。
如果參數oldact不是NULL指針,則原來的信號處理方式會由此結構sigaction 返回。

返回值 執行成功則返回0,如果有錯誤則返回-1。

錯誤代碼 EINVAL 參數signum 不合法,或是企圖攔截SIGKILL/SIGSTOPSIGKILL信號
EFAULT 參數act,oldact指針地址無法存取。
EINTR 此調用被中斷

範例 #include<unistd.h>
#include<signal.h>
void show_handler(struct sigaction * act)
{
switch (act->sa_flags)
{
case SIG_DFL:printf("Default action\n");break;
case SIG_IGN:printf("Ignore the signal\n");break;
default: printf("0x%x\n",act->sa_handler);
}
}
main()
{
int i;
struct sigaction act,oldact;
act.sa_handler = show_handler;
act.sa_flags = SA_ONESHOT|SA_NOMASK;
sigaction(SIGUSR1,&act,&oldact);
for(i=5;i<15;i++)
{
printf("sa_handler of signal %2d =".i);
sigaction(i,NULL,&oldact);
}
}

執行 sa_handler of signal 5 = Default action
sa_handler of signal 6= Default action
sa_handler of signal 7 = Default action
sa_handler of signal 8 = Default action
sa_handler of signal 9 = Default action
sa_handler of signal 10 = 0x8048400
sa_handler of signal 11 = Default action
sa_handler of signal 12 = Default action
sa_handler of signal 13 = Default action
sa_handler of signal 14 = Default action

5.sigaddset(增加一個信號至信號集)
相關函數 sigemptyset,sigfillset,sigdelset,sigismember

表頭文件 #include<signal.h>

定義函數 int sigaddset(sigset_t *set,int signum);

函數說明 sigaddset()用來將參數signum 代表的信號加入至參數set 信號集裏。

返回值執行成功則返回0,如果有錯誤則返回-1。

錯誤代碼 EFAULT 參數set指針地址無法存取
EINVAL 參數signum非合法的信號編號

6.sigdelset(從信號集裏刪除一個信號)

相關函數 sigemptyset,sigfillset,sigaddset,sigismember

表頭文件 #include<signal.h>

定義函數 int sigdelset(sigset_t * set,int signum);

函數說明 sigdelset()用來將參數signum代表的信號從參數set信號集裏刪除。

返回值 執行成功則返回0,如果有錯誤則返回-1。

錯誤代碼 EFAULT 參數set指針地址無法存取
EINVAL 參數signum非合法的信號編號

7.sigemptyset(初始化信號集)
相關函數 sigaddset,sigfillset,sigdelset,sigismember

表頭文件 #include<signal.h>

定義函數 int sigemptyset(sigset_t *set);

函數說明 sigemptyset()用來將參數set信號集初始化並清空。

返回值 執行成功則返回0,如果有錯誤則返回-1。

錯誤代碼 EFAULT 參數set指針地址無法存取

8.sigfillset(將所有信號加入至信號集)
相關函數 sigempty,sigaddset,sigdelset,sigismember

表頭文件 #include<signal.h>

定義函數 int sigfillset(sigset_t * set);

函數說明 sigfillset()用來將參數set信號集初始化,然後把所有的信號加入到此信號集裏。

返回值 執行成功則返回0,如果有錯誤則返回-1。

附加說明 EFAULT 參數set指針地址無法存取

9.sigismember(測試某個信號是否已加入至信號集裏)

相關函數 sigemptyset,sigfillset,sigaddset,sigdelset

表頭文件 #include<signal.h>

定義函數 int sigismember(const sigset_t *set,int signum);

函數說明 sigismember()用來測試參數signum 代表的信號是否已加入至參數set信號集裏。如果信號集裏已有該信號則返回1,否則返回0。

返回值信號集已有該信號則返回1,沒有則返回0。如果有錯誤則返回-1。

錯誤代碼 EFAULT 參數set指針地址無法存取
EINVAL 參數signum 非合法的信號編號

10.signal(設置信號處理方式)

相關函數 sigaction,kill,raise

表頭文件 #include<signal.h>

定義函數 void (*signal(int signum,void(* handler)(int)))(int);

函數說明 signal()會依參數signum 指定的信號編號來設置該信號的處理函數。當指定的信號到達時就會跳轉到參數handler指定的函數執行。如果參數handler不是函數指針,則必須是下列兩個常數之一:
SIG_IGN 忽略參數signum指定的信號。
SIG_DFL 將參數signum 指定的信號重設爲核心預設的信號處理方式。
關於信號的編號和說明,請參考附錄D

返回值返回先前的信號處理函數指針,如果有錯誤則返回SIG_ERR(-1)。

附加說明在信號發生跳轉到自定的handler處理函數執行後,系統會自動將此處理函數換回原來系統預設的處理方式,如果要改變此操作請改用sigaction()。

範例 參考alarm()或raise()。

11.sigpending(查詢被擱置的信號)

相關函數 signal,sigaction,sigprocmask,sigsuspend

表頭文件 #include<signal.h>

定義函數 int sigpending(sigset_t *set);

函數說明 sigpending()會將被擱置的信號集合由參數set指針返回。

返回值執 行成功則返回0,如果有錯誤則返回-1。

錯誤代碼 EFAULT 參數set指針地址無法存取
EINTR 此調用被中斷。

12.sigprocmask(查詢或設置信號遮罩)

相關函數 signal,sigaction,sigpending,sigsuspend

表頭文件 #include<signal.h>

定義函數 int sigprocmask(int how,const sigset_t *set,sigset_t * oldset);

函數說明 sigprocmask()可以用來改變目前的信號遮罩,其操作依參數how來決定
SIG_BLOCK 新的信號遮罩由目前的信號遮罩和參數set 指定的信號遮罩作聯集
SIG_UNBLOCK 將目前的信號遮罩刪除掉參數set指定的信號遮罩
SIG_SETMASK 將目前的信號遮罩設成參數set指定的信號遮罩。
如果參數oldset不是NULL指針,那麼目前的信號遮罩會由此指針返回。

返回值 執行成功則返回0,如果有錯誤則返回-1。

錯誤代碼 EFAULT 參數set,oldset指針地址無法存取。
EINTR 此調用被中斷

13.sleep(讓進程暫停執行一段時間)
相關函數 signal,alarm

表頭文件 #include<unistd.h>

定義函數 unsigned int sleep(unsigned int seconds);

函數說明 sleep()會令目前的進程暫停,直到達到參數seconds 所指定的時間,或是被信號所中斷。

返回值 若進程暫停到參數seconds 所指定的時間則返回0,若有信號中斷則返回剩餘秒數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章