日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Linux系統(tǒng)編程 | 信號的產(chǎn)生

 西北望msm66g9f 2018-07-23


本文字數(shù):2108字

閱讀時間:6分鐘



作者

良許

一個熱愛技術(shù)的程序猿


終端按鍵產(chǎn)生信號


ctrl + c

發(fā)送2號信號SIGINT,將中止當前進程。SIGINT的“INT”是interrupt的意思;


ctrl + z

發(fā)送20號信號SIGTSTP,暫停/停止當前進程。SIGTSTP中的“T”是terminal的意思。進程收到此信號后,將由當前轉(zhuǎn)入后臺,可用ps aux找到它。


比如說,我們使用vim編寫代碼時,需要在vim以外處理一些事情,但又不想退出vim,可用ctrl + z命令讓vim進程進入后臺,之后再用fg命令重新將vim進程喚回前臺,繼續(xù)編輯;


ctrl + \

發(fā)送 3號信號SIGQUIT給前臺進程組中的所有進程,終止前臺進程并生成 core 文件;


硬件異常產(chǎn)生信號


a. 除0操作

產(chǎn)生8號信號SIGFPE,終止進程并產(chǎn)生core文件。SIGFPE的“F”是float的意思;


b. 非法訪問內(nèi)存

產(chǎn)生11號信號SIGSEGV,段錯誤;


c. 總線錯誤

產(chǎn)生7號信號SIGBUS;



kill函數(shù)/命令產(chǎn)生信號


從字面上來看,kill是殺死的意思,但這個命令/函數(shù)真正的意思是向進程發(fā)送信號。真不知道當時設(shè)計這個命令/函數(shù)的人是怎么想的。


kill命令使用方法:


kill -信號編號/宏 進程號。比如:kill -SIGKILL 1893,表示發(fā)送SIGKILL信號給1893號進程,即殺死1893號進程。


kill函數(shù)的用法:


函數(shù)原型:

int kill(pid_t pid, int sig); 


返回值:

成功:返回0;失?。悍祷?1,并設(shè)置errno。


參數(shù)說明:

sig:要發(fā)送的信號,最好寫宏名,而不要寫信號編號,因為各個平臺信號的編號可能不一樣,而宏名都是維一的;

pid:要發(fā)送的目標進程;

pid > 0:發(fā)送信號給進程號為pid的進程;

pid = 0:發(fā)送信號給與調(diào)用kill函數(shù)進程屬于同一進程組的所有進程;

pid <>

pid = -1:發(fā)送給進程有權(quán)限發(fā)送的系統(tǒng)中所有進程。啥是“有權(quán)限發(fā)送”?比如你就不能給init進程發(fā)信號,因為你沒權(quán)限。


例程:

循環(huán)創(chuàng)建5個進程,并殺死第三個子進程。

1#include 
2#include 
3#include 
4#include 
5
6
7#define N 5
8
9int main()
10
{
11        int i = 0;
12        pid_t pid, q;
13
14        for (i = 0; i <>
15                /* 循環(huán)創(chuàng)建N個子進程 */
16                pid = fork();
17                if (pid == -1)
18                        printf('ERROR: fork error!\n');
19                else if (pid == 0)
20                        break;
21
22                if (i == 2)
23                        q = pid;        // 保留第三個子進程的pid
24        }
25
26        if (i <>
27                while (1) {
28                        printf('I'm %dth child process, pid = %d\n', i, getpid());
29                        sleep(1);
30                }
31        } else if (i == N) {
32                sleep(1);
33                printf('I'm parent process\n');
34                kill(q, SIGKILL);
35                while (1);
36        }
37
38        return 0;
39}


raise和abort函數(shù)


rase函數(shù):

int raise(int sig); 成功:返回0,失?。悍祷胤?值。

給當前進程發(fā)送指定信號。簡單一句話:自己給自己發(fā)信號。


abort函數(shù):

void abort(void); 無返回值。

給自己發(fā)送異常終止信號SIGABRT,終止進程并產(chǎn)生core文件。


alarm函數(shù)


函數(shù)原型:

unsigned int alarm(unsigned int seconds); 


返回值:

返回0或者上次鬧鐘剩余秒數(shù),無失敗情況;


函數(shù)作用:

設(shè)置定時器,在指定時間之后,內(nèi)核給調(diào)用alarm的函數(shù)發(fā)送SIGALRM信號。進程收到該信號后,默認動作是終止當前進程。


每個進程有且只有一個定時器,并且與進程的狀態(tài)無關(guān)。也就是說,不管進程處于就緒、運行、掛起(阻塞/暫停)、終止、僵尸、孤兒,alarm定時器一直都在計時。


常見用法:

alarm(5); --> 5秒后發(fā)送SIGALRM信號。如果在2秒后調(diào)用alarm(2),則alarm(2)返回值是3,并且在2秒后發(fā)送SIGALRM信號;

alarm(0); --> 取消定時器,并返回上次調(diào)用alarm剩下的秒數(shù)。


1#include 
2#include 
3
4int main()
5
{
6        unsigned int t = 0;
7        printf('process start..\n');
8        alarm(10);
9        sleep(2);
10        t = alarm(2);
11        printf('time left: %d\n', t);
12        while (1);      // 進程停在此處,直到收到定時器信號SIGALRM將進程殺死
13
14        return 0;
15}



setitimer函數(shù)


與alarm類似,可設(shè)置定時器,但是,alarm函數(shù)定時精度只能到秒,而setitimer函數(shù)定時可達到微秒級,并且可以周期定時。


函數(shù)原型:

int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);


返回值:

成功:返回0;失敗:返回-1,并設(shè)置errno。


參數(shù)說明:

參數(shù)which:指定定時方式:

a. 自然定時:ITIMER_REAL。計算程序運行自然時間,就是程序不管在內(nèi)核態(tài)還是用戶態(tài),都計時。到達時間點后,發(fā)送SIGARM信號;

b. 用戶空間定時:ITIMER_VIRTUAL。只計算進程戰(zhàn)勝CPU的時間,即用戶空間時間。到達時間點后,發(fā)送SIGVTALRM信號;

c. 運行時計時:ITIMER_PROF。計算占用cpu及執(zhí)行系統(tǒng)調(diào)用的時間,也即用戶空間時間及內(nèi)核時間總和。到達時間點后,發(fā)送SIGPROF信號。

這三種定時方式,最常用的就是自然定時法,即參數(shù)為ITIMER_REAL的定時方式,而后兩種方式不常用,有用到時再查手冊。


結(jié)構(gòu)體struct itimerval有兩個成員,一個是it_value, 另一個是it_interval。他們倆都是可以精確到微秒的,以struct timeval來控制具體時間。it_value控制了多久之后第一次發(fā)送信號,之后會循環(huán)發(fā)送,間隔是it_interval。


參數(shù)new_value:設(shè)定的定時時間;


參數(shù)old_value:上次調(diào)用setitimer剩余的時間。


例程:

自己實現(xiàn)alarm函數(shù):


1#include 
2#include 
3#include 
4#include 
5
6unsigned int my_alarm(unsigned int sec)
7
{
8        struct itimerval new_valueold_value;
9        int ret = -1;
10
11        new_value.it_value.tv_sec = sec;
12        new_value.it_value.tv_usec = 0;
13        new_value.it_interval.tv_sec = 0;
14        new_value.it_interval.tv_usec = 0;
15
16        ret = setitimer(ITIMER_REAL, &new_value, &old_value);
17        if (ret == -1) {
18                printf('ERROR: setitimer error!\n');
19                exit(1);
20        }
21        return old_value.it_value.tv_sec;
22}
23
24int main()
25
{
26        unsigned int t = 0;
27        printf('process start..\n');
28        alarm(10);
29        sleep(2);
30        t = alarm(2);
31        printf('time left: %d\n', t);
32        while (1);      // 進程停在此處,直到收到定時器信號SIGALRM將進程殺死
33
34        return 0;
35}


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多