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

歡迎訪問 生活随笔!

生活随笔

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

linux

linux信号值头文件位置,Linux C 信号处理机制

發布時間:2023/12/10 linux 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux信号值头文件位置,Linux C 信号处理机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一 . 信號

1. 信號:是內核發送給某一進程的一種消息 。

2. 信號機制:是Linux系統中用于進程之間相互通信或操作的一種機制。

3. 信號的來源:信號來源于內核

4. 產生原因: (1)用戶通過終端輸入 (2)進程執行(3)一個進程調用kill向另一個進程發送信號

5. 信號分類:1)同步信號 ? ?異步信號

2)可靠信號 : 信號被遞送多次 ?不可靠信號: 只被遞送一次的信號

6. 信號處理方式

A.? 按系統默認方式處理 ——每個信號都有一個默認動作,典型的默認動作是終止進程。 man signal 7 列出系統對各信號的默認處理 。

B.? 忽略信號——接收信號,但是不做任何操作 。

C. ?捕捉信號——程序提前告訴內核,當信號到來時應該調用哪個函數。

二. 信號相關函數

1. ?簡單的信號處理

函數原型: sighandler_t signal(int signum, sighandler_t handler);

參 ? ?數:signum ——要響應的信號,handler ?——信號發生時要執行的操作。

返回值:非-1 ? ?執行成功,返回以前的信號處理函數指針

-1 ? ? ? ?遇到錯誤

//捕捉信號

#include

#include

#include

#include

void capture(int signum){

printf("SIGINT is capture!\n");

}

int main(int argc, char *argv[]){

int i=10;

if(signal(SIGINT,capture) == SIG_ERR){

printf("Can't catch SIGINT");

exit(1);

}

printf("waiting for signal...\n");

while(i > 0){

printf("Now i=%d \n",i);

sleep(1);

i--;

}

return 0;

}

//忽略信號

#include

#include

#include

int main(int argc,char *argv[]){

int i=10;

signal(SIGINT,SIG_IGN);

printf("waiting for signal ...\n");

while(i > 0){

sleep(1);

i--;

printf("Now i = %d,but you can't stop this program by Ctrl + C\n",i);

}

return 0;

}

//恢復信號的默認處理

#include

#include

void capthensfl(int signum){

printf("SIGINT is capture !\n");

signal(SIGINT,SIG_DFL);

printf("SIGINT now is defaulted !\n");

}

int main(int argc,char *argv[]){

int i=10;

signal(SIGINT,capthensfl);

printf("waiting for signal...\n");

while(i > 0){

sleep(1);

printf("Now i = %d\n",i);

i--;

}

return 0;

}

2. 信號處理函數:指定一個信號的處理函數

函數原型:int sigaction(int signum, struct sigaction *action, struct sigaction *oldaction);

參 ? ?數:signum ?,要處理的信號

action ? ? ? ?要安裝的信號處理操作的結構

oldaction ? 之前的信號處理操作的結構

返回值:0? ? 成功 ? ? -1,失敗

說 ? ?明:oldaction不為NULL,則用其來存儲以前設置的與此信號關聯的操作。

action不為NULL: 則指定信號關聯的操作為此參數指向的結構 否則,信號處理保持不變。(此方式用來查詢當前對指定信號的處理方式)

sigaction的結構:

struct sigaction{

union{ ?? ??? ?__sighandler_t _sa_handler;

void(*_sa_sigaction)(int , struct siginfo *, void *);

} __u;

sigset_t sa_mask;

unsigned long sa_flags;

};

sa_sigaction的說明: void (*sa_sigaction)(int, struct siginfo *,void *);

第一個參數:要響應的信號 。

第二個參數:記錄導致產生信號的原因、類型等 。

第三個參數:信號發生時被中斷的上下文環境 信號能傳遞簡單的信息。

//使用sa_sigaction類型函數

#include

#include

#include

#include

void fun(int signo, siginfo_t *info, void *context){

printf("Test for sa_sigaction !\n");

}

int main(int argc,char *argv[]){

struct sigaction action,oldaction;

sigemptyset(&action.sa_mask);

action.sa_flags=SA_SIGINFO;

action.sa_sigaction=fun;

sigaction(SIGINT,&action,&oldaction);

printf("waiting for signal...\n");

while(1){

pause();

}

return 0;

}

3.?初始化信號集

函數原型:int sigemptyset(sigset_t ?*set);

int sigfillset(sigset_t ?*set);

參 ? ?數:set ?待初始化的信號集

返回值:0? ?成功 ? ? -1,失敗

4.?添加、刪除信號

函數原型:int sigaddset(sigset_t *set, int signo);

int sigdelset(sigset_t *set, int signo);

參 ? ?數:set ?待初始化的信號集 . ?signo ?待添加/刪除的信號編號

返回值:0? 成功 ? ? -1,失敗

5.?修改屏蔽信號集

函數原型:int sigprocmask(int how,sigset_t *set, sigset_t * oldset);

參 ? ?數:how ? 如何修改信號掩碼

set?要使用的信號集

oldset ? 之前的信號集

返回值:0? 成功 ? ? -1,失敗

對參數how的說明: ? ?SIG_BLOCK:信號集中增加set中的信號

SIG_UNBLOCK:信號集中刪除set中的信號

SIG_SETMASK:信號集被設置為set信號集

三. ?系統調用函數

1.?kill ?—— 向進程發送一個信號

函數原型:int kill(pid_t pid, int sig);

參 ? ?數:pid 目標進程id,?sig ?要發送的信號

返回值:0? 成功 ? ? -1,失敗

說 ? ?明: ? ? pid>0 ? ? ?目標進程的進程號為pid

pid=0 ? ? ?將信號發送給和當前進程在同一進程租的所有進程

pid=-1 ? ? 將信號發送給系統內的所有進程

pid<0 ? ? ?將信號發送給進程組號PGID為pid絕對值的所有進程

一個進程可使用kill函數將信號發送給另一進程或進程組。

要求:發送信號的進程的用戶ID和目標進程的用戶ID相同,或發送信號的進程的owner是一個超級用戶。

//kill 使用示例

#include

#include

#include

void fun(int signo){

printf("Process capture SIGINT");

signal(SIGINT,SIG_DFL);

}

int main(int argc,char *argv[]){

int pid;

if((pid=fork()) == -1){

perror("fork");

exit(EXIT_FAILURE);

}

else if( pid == 0){

signal(SIGINT,fun);

printf("Child %d waiting for parent %d send signal\n",getpid(),getppid());

pause();

pause();

}

else{

sleep(1);

printf("Parent %d will send signal to child %d \n",getppid(),getpid());

kill(pid,SIGINT);

wait(NULL);

}

return 0;

}

2.?raise ——?自舉一個信號

函數原型:int raise(int signo);

參 ? ?數:signo ? ? ?待發送的信號

返回值:0? 成功 ? ? -1,失敗

說 ? 明:raise(signo)=kill(getpid(),signo)

3.?alarm ——?設置計時器

函數原型:int alarm(int seconds);

參 ? ?數:seconds ?計時的秒數

返回值: ? ? ?0 ? ?之前未調用過alarm

>0 ? 之前調用alarm設置的鬧鐘時間的余留秒數

4.?pause ——?掛起調用進程

函數原型:int pause(void);

返回值:-1 ? ? ? 并將errno設置為EINTR

四. 信號集合操作應用示例

/* ?信號的應用示例:

父進程執行文件復制操作,如果收到SIGUSR1信號,就打印出當前的復制進度

子進程每隔一個固定時間向父進程發送SIGUSR1信號

*/

#include

#include

#include

#include

#include

#include

int count; ?//當前復制大小

int file_size; //文件的大小

//父進程對SIGUSR1信號的處理函數

void sig_usr(int signum){

float i;

//求出復制進程

i = (float)count/(float)file_size;

printf("current over : %0.0f%%\n",i*100);

}

//子進程對SIGUSR1信號的處理,即向父進程發送SIGUSR1信號

void sig_alarm(int signo){

kill(getppid(),SIGUSR1);

}

//主函數

int main(int argc ,char *argv[]){

pid_t pid;

int i;

int fd_src,fd_des;

char buf[128];

if(argc != 3){

printf("the format must be : command src_file des_file \n");

return -1;

}

//以只讀方式打開源文件

if((fd_src = open(argv[1],O_RDONLY)) == -1){

perror("open fd_src");

exit(EXIT_FAILURE);

}

//獲取源文件大小

file_size = lseek(fd_src,0,SEEK_END);

//重新設置讀寫位置為文件頭

lseek(fd_src,0,SEEK_SET);

//以讀寫方式打開目標文件,如果不存在就創建

if((fd_des = open(argv[2],O_RDWR|O_CREAT,0644)) == -1){

perror("open fd_des");

exit(EXIT_FAILURE);

}

//進程創建失敗

if((pid = fork() == -1)){

perror("fork");

exit(EXIT_FAILURE);

}

//父進程

else if(pid > 0){

//安裝信號

signal(SIGUSR1,sig_usr);

do{

memset(buf,'\0',128);

//復制數據

if((i = read(fd_src,buf,1)) == -1){

perror("read");

exit(EXIT_FAILURE);

}

//如果復制完成,向子進程發送SIGINT信號,終止

else if(i == 0){

kill(pid,SIGINT);

break;

}

else{

//執行復制操作

if(write(fd_des,buf,i) == -1){

perror("write");

exit(EXIT_FAILURE);

}

count += i; //更新已經復制的文件的大小

}

}while(i != 0);

//等待子進程退出

wait(pid,NULL,0);

exit(EXIT_SUCCESS);

}

//子進程

else if(pid == 0){

usleep(1);

signal(SIGALRM,sig_alarm);

ualarm(1,1);

while(i){

;

}

exit(EXIT_SUCCESS);

}

return 0;

}

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的linux信号值头文件位置,Linux C 信号处理机制的全部內容,希望文章能夠幫你解決所遇到的問題。

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