程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Linux下C編程:signal和sigaction

Linux下C編程:signal和sigaction

編輯:關於C語言

要對一個信號進行處理,就需要給出此信號發生時系統所調用的處理函數。可以對一個特定的信號(除去SIGKILL和SIGSTOP信號)注冊相應的處理函數。注冊某個信號的處理函數後,當進程接收到此信號時,無論進程處於何種狀態,就會停下當前的任務去執行此信號的處理函數。

1、注冊信號函數。

#include<signal.h>     
         
void(*signal(int signumber,void ((*func)(int))(int)

signumber表示信號處理函數對應的信號。func是一個函數指針。此函數有一整型參數,並返回void型。其實func還可以取其他定值如:SIG_IGN,SIG_DFL.

SIG_IGN表示:忽略signumber所指出的信號。SIG_DFL表示表示調用系統默認的處理函數。signal函數的返回值類型同參數func,是一個指向某個返回值為空並帶有一個整型參數的函數指針。其正確返回值應為上次該信號的處理函數。錯誤返回SIG_ERR

signal示例如下:

#include <stdio.h>

#include <sys/types.h>

#include <stdlib.h>

#include <signal.h>

void func(int sig)
{
printf("I get asignal!\n");
}
int main()
{    charbuffer[100];

   if(signal(SIGINT, func) == SIG_ERR)
     {
     printf("signalerror exit now\n");
     exit(0);
     }
     printf("pid:%ld\n",(long)getpid());

   for(;;) 

     {

     fgets(buffer,sizeof(buffer),stdin);

     printf("bufferis:%s\n",buffer);

     }
 return 0;      
}

通常情況下一個用戶進程需要處理多個信號。可以在一個程序中注冊多個信號處理函數。一個信號可以對應一個處理函數,同時多個信號可以對應一個處理函數。

對於SIGINT信號 我們可以用ctrl+c或ctrl+z來中斷進程,來執行SIGINT注冊的函數。

2、 高級信號處理。

在linux系統提供了一個功能更強的系統調用。

#include <signal.h>     
         
int sigaction(int signumbet,const structsigaction *act,struct sigaction *oldact)

此函數除能注冊信號函數外還提供了更加詳細的信息,確切了解進程接收到信號,發生的具體細節。

struct sigaction的定義如下:在linux2.6.39/include/asm-generic/signal.h中實現

struct sigaction     

{ 

     void(*sa_handler)(int);

     void(*sa_sigaction)(int,siginfo_t *,void *);

     sigset_tsa_mask;

     intsa_flags;

}

siginfo_t在linux2.6.39/include/asm-generic/siginfo.h中實現:

sa_flags的取值如下表,取0表示選用所有默認選項。

SA_NOCLDSTOP:用於表示信號SIGCHLD,當子進程被中斷時,不產生此信號,當且僅當子進程結束時產生此信號。

SA_NOCLDWATI:當信號為SIGCHLD,時可避免子進程僵死。

SA_NODEFER:當信號處理函數正在進行時,不堵塞對於信號處理函數自身信號功能。

SA_NOMASK:同SA_NODEFER

SA_ONESHOT:當用戶注冊的信號處理函數被執行過一次後,該信號的處理函數被設為系統默認的處理函數。

SA_RESETHAND:同SA_ONESHOT

SA_RESTART:是本來不能重新於運行的系統調用自動重新運行。

SA_SIGINFO:表明信號處理函數是由SA_SIGACTION指定的,而不是由SA_HANDLER指定的,它將顯示更多的信號處理函數信息。

其實sinaction完全可以替換signal函數

#include <stdio.h> 
#include <sys/types.h> 
#include <stdlib.h>
#include <signal.h>

void func(int sig) 

{ 

printf("I get a signal!\n");

}

int main()

{   char buffer[100];

    struct sigaction act;
    act.sa_handler=func;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;

    if(sigaction(SIGINT,&act, NULL) == -1) 
    { 
    printf("sigaction error exit now\n");
    exit(0);
    }

    printf("pid:%ld\n",(long)getpid());

    for(;;)
    {
    fgets(buffer,sizeof(buffer),stdin); 
    printf("buffer is:%s\n",buffer); 
    }

    return 0;

}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved