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

歡迎訪問 生活随笔!

生活随笔

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

linux

Linux下的signal信号机制

發布時間:2023/11/29 linux 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux下的signal信号机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在Linux中,要發送一個信號相當容易。程序員需要知道兩個信息:要發送哪個信號,將這個信號發送給哪個進程??梢杂?man 7 signal 找到一個可以利用的信號的列表。用戶可以只將信號發送給用戶自己的進程,也可以以root身份運行從而將信號發送給任意一進程。

?

Source:

#include<stdio.h> #include<signal.h> #include<unistd.h> #include<stdlib.h> void when_alarm(); void when_sigint(); void when_sigchld(int); void when_sigusr1(); void when_sigio(); int main() { int childpid;//子程序進程ID號 printf("程序已經開始運行,5秒鐘后將接收到時鐘信號。/n"); if ((childpid=fork())>0)//父進程 { signal(SIGALRM,when_alarm); //當接收到SIGALRM信號時,調用when_alarm函數 signal(SIGINT,when_sigint); //當接收到SIGINT信號時,調用when_sigint函數 signal(SIGCHLD,when_sigchld);//當接收到SIGCHLD信號時,調用when_sigchld函數 signal(SIGUSR1,when_sigusr1);//當接收到SIGUSR1信號時,調用when_sigusr1函數 signal(SIGIO,when_sigio);//當接收到SIGIO信號時,調用when_sigio函數 alarm(5); //5秒鐘之后產生SIGALRM信號 raise(SIGIO); //向自己發送一個SIGIO信號 pause(); //將父進程暫停下來,等待SIGALRM信號到來 pause(); //將父進程暫停下來,等待SIGUSR1信號到來 pause(); //將父進程暫停下來,等待SIGCHLD信號到來 printf("------此時程序會停下來等待,請按下ctrl+c送出SIGINT信號-------/n"); pause(); //將父進程暫停下來,等待SIGINT信號到來 } else if(childpid==0) //子進程 { int timer; for(timer=7;timer>=0;timer--) //時鐘計時5秒產生SIGALRM信號,再過2秒子進程退出,產生SIGCHLD信號 { if(timer>2) printf("距離SIGALRM信號到來還有%d秒。/n",timer-2); if(timer==4) kill(getppid(),SIGUSR1); //向父進程發送一個SIGUSR1信號 if((timer<=2)&&(timer>0)) printf("子進程還剩%d秒退出,屆時會產生SIGCHLD信號。/n",timer); if(timer==0) //子進程退出,產生SIGCHLD信號 raise(SIGKILL); //子進程給自己發一個結束信號 sleep(1); //每個循環延時1秒鐘 } } else printf("fork()函數調用出現錯誤!/n"); return 0; } void when_alarm() { printf("5秒鐘時間已到,系統接收到了SIGALRM信號!/n"); } void when_sigint() { printf("已經接收到了SIGINT信號,程序將退出!/n"); exit(0); } void when_sigchld(int SIGCHLD_num) { printf("收到SIGCHLD信號,表明我的子進程已經中止,SIGCHLD信號的數值是:%d。/n",SIGCHLD_num); } void when_sigusr1() { printf("系統接收到了用戶自定義信號SIGUSR1。/n"); } void when_sigio() { printf("系統接收到了SIGIO信號。/n"); } ?

?

Result:

?

[work@db-testing-com06-vm3.db01.baidu.com c++]$ ./signal_test?

程序已經開始運行,5秒鐘后將接收到時鐘信號。

距離SIGALRM信號到來還有5秒。

系統接收到了SIGIO信號。

距離SIGALRM信號到來還有4秒。

距離SIGALRM信號到來還有3秒。

距離SIGALRM信號到來還有2秒。

系統接收到了用戶自定義信號SIGUSR1。

距離SIGALRM信號到來還有1秒。

5秒鐘時間已到,系統接收到了SIGALRM信號!

子進程還剩2秒退出,屆時會產生SIGCHLD信號。

子進程還剩1秒退出,屆時會產生SIGCHLD信號。

收到SIGCHLD信號,表明我的子進程已經中止,SIGCHLD信號的數值是:17。

------此時程序會停下來等待,請按下ctrl+c送出SIGINT信號-------

已經接收到了SIGINT信號,程序將退出!

?

?

信號參考對照表:

Signal

Description

SIGABRT

由調用abort函數產生,進程非正常退出

SIGALRM

alarm函數設置的timer超時或setitimer函數設置的interval timer超時

SIGBUS

某種特定的硬件異常,通常由內存訪問引起

SIGCANCEL

Solaris Thread Library內部使用,通常不會使用

SIGCHLD

進程TerminateStop的時候,SIGCHLD會發送給它的父進程。缺省情況下該Signal會被忽略

SIGCONT

當被stop的進程恢復運行的時候,自動發送

SIGEMT

和實現相關的硬件異常

SIGFPE

數學相關的異常,如被0除,浮點溢出,等等

SIGFREEZE

Solaris專用,Hiberate或者Suspended時候發送

SIGHUP

發送給具有TerminalControlling Process,當terminaldisconnect時候發送

SIGILL

非法指令異常

SIGINFO

BSD signal。由Status Key產生,通常是CTRL+T。發送給所有Foreground Group的進程

SIGINT

Interrupt Key產生,通常是CTRL+C或者DELETE。發送給所有ForeGround Group的進程

SIGIO

異步IO事件

SIGIOT

實現相關的硬件異常,一般對應SIGABRT

SIGKILL

無法處理和忽略。中止某個進程

SIGLWP

Solaris Thread Libray內部使用

SIGPIPE

reader中止之后寫Pipe的時候發送

SIGPOLL

當某個事件發送給Pollable Device的時候發送

SIGPROF

Setitimer指定的Profiling Interval Timer所產生

SIGPWR

和系統相關。和UPS相關。

SIGQUIT

輸入Quit Key的時候(CTRL+/)發送給所有Foreground Group的進程

SIGSEGV

非法內存訪問

SIGSTKFLT

Linux專用,數學協處理器的棧異常

SIGSTOP

中止進程。無法處理和忽略。

SIGSYS

非法系統調用

SIGTERM

請求中止進程,kill命令缺省發送

SIGTHAW

Solaris專用,從Suspend恢復時候發送

SIGTRAP

實現相關的硬件異常。一般是調試異常

SIGTSTP

Suspend Key,一般是Ctrl+Z。發送給所有Foreground Group的進程

SIGTTIN

Background Group的進程嘗試讀取Terminal的時候發送

SIGTTOU

Background Group的進程嘗試寫Terminal的時候發送

SIGURG

out-of-band data接收的時候可能發送

SIGUSR1

用戶自定義signal 1

SIGUSR2

用戶自定義signal 2

SIGVTALRM

setitimer函數設置的Virtual Interval Timer超時的時候

SIGWAITING

Solaris Thread Library內部實現專用

SIGWINCH

Terminal的窗口大小改變的時候,發送給Foreground Group的所有進程

SIGXCPU

CPU時間限制超時的時候

SIGXFSZ

進程超過文件大小限制

SIGXRES

Solaris專用,進程超過資源限制的時候發送

==========================================================================

signal學習推薦:


信號(signal)介紹(Linux中國)

http://www.linux-cn.com/html/linux/system/20070505/27605.shtml

?

Linux 信號signal處理函數(CSDN)

http://blog.csdn.net/Sunboy_2050/archive/2010/10/16/5945535.aspx

?

Linux 信號signal處理機制(CSDN)

http://blog.csdn.net/Sunboy_2050/archive/2010/10/16/5945380.aspx

?

==========================================================================
???????? 程序員可以調用 int raise(int signo) 將一個信號發送給它自己。這個函數只帶有一個參數,既要發送信號的編號。如:raise(SIGINT); raise(SIGKILL);
???????? 讓人感興趣的是函數 unsigned int alarm(unsigned int seconds) 它可以讓用戶進程在將來某個指定的時間接收到一個信號。alarm()的唯一參數是將來信號SIGALRM應該在多少秒以后發送給用戶進程。當用戶調用alarm()時,前面任何一個請求的報警信號(不包括懸掛起來被阻塞的SIGALRM信號)都將被取消,調用的返回值是前面請求的剩余時間。alarm()范例如下:
????
if(signal(SIGALRM,alarmhandler)==SIG_ERR)
{
???? printf("Couldn't register signal handler./n");?
}
alarm(5);????? // 5秒鐘以后,程序將會收到一個SIGALRM信號
for(i=0;i<10;i++)
{
???? sleep(3);
}
void alarmhandler(int signum)
{
???? printf("alarmhandler./n");?
}

???????? 也可以使用 int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue) 來實現更精確更方便的定時控制。
???????? 參數which一般取ITIMER_REAL,它使得用戶的計時器根據系統時鐘來計算時間。當計數時間到期時,它將發送一個SIGALRM信號。其功能和alarm()一樣,所以用戶不能將兩者同時使用。
???????? 結構itimerval的定義如下:
struct itimerval?
{?
???? struct timeval it_interval; // 每一次觸發報警后應該被復位的值,為0報警被禁止
???? struct timeval it_value;???? // 下一次觸發報警的時間,為0報警將只觸發一次
};
???????? 結構timeval的定義如下:
strut timeval
{?
???? long tv_sec;?????? // 秒數?
???? long tv_usec;???? // 微秒數
};
???????? setitimer()范例如下:

struct itimerval itimer;
itimer.it_interval.tv_usec = 0;???? // it_interval字段指定了每一次觸發后應該被復位的值
itimer.it_interval.tv_sec???? = 2;

itimer.it_value.tv_usec = 0;??????? // it_value字段指定了直到下一次觸發的時間???
itimer.it_value.tv_sec???? = 5;
setitimer(ITIMER_REAL,&itimer,NULL);

for(i=0;i<10;i++)
{
???? sleep(3);
}

void alarmhandler(int signum)
{
???? printf("alarmhandler./n");?
}

總結

以上是生活随笔為你收集整理的Linux下的signal信号机制的全部內容,希望文章能夠幫你解決所遇到的問題。

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