乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

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

       西北望msm66g9f 2018-07-23


      本文字?jǐn)?shù):2108字

      閱讀時(shí)間:6分鐘



      作者

      良許

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


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


      ctrl + c

      發(fā)送2號(hào)信號(hào)SIGINT,將中止當(dāng)前進(jìn)程。SIGINT的“INT”是interrupt的意思;


      ctrl + z

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


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


      ctrl + \

      發(fā)送 3號(hào)信號(hào)SIGQUIT給前臺(tái)進(jìn)程組中的所有進(jìn)程,終止前臺(tái)進(jìn)程并生成 core 文件;


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


      a. 除0操作

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


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

      產(chǎn)生11號(hào)信號(hào)SIGSEGV,段錯(cuò)誤;


      c. 總線錯(cuò)誤

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



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


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


      kill命令使用方法:


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


      kill函數(shù)的用法:


      函數(shù)原型:

      int kill(pid_t pid, int sig); 


      返回值:

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


      參數(shù)說明:

      sig:要發(fā)送的信號(hào),最好寫宏名,而不要寫信號(hào)編號(hào),因?yàn)楦鱾€(gè)平臺(tái)信號(hào)的編號(hào)可能不一樣,而宏名都是維一的;

      pid:要發(fā)送的目標(biāo)進(jìn)程;

      pid > 0:發(fā)送信號(hào)給進(jìn)程號(hào)為pid的進(jìn)程;

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

      pid <>

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


      例程:

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

      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個(gè)子進(jì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;        // 保留第三個(gè)子進(jìn)程的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,失?。悍祷胤?值。

      給當(dāng)前進(jìn)程發(fā)送指定信號(hào)。簡單一句話:自己給自己發(fā)信號(hào)。


      abort函數(shù):

      void abort(void); 無返回值。

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


      alarm函數(shù)


      函數(shù)原型:

      unsigned int alarm(unsigned int seconds); 


      返回值:

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


      函數(shù)作用:

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


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


      常見用法:

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

      alarm(0); --> 取消定時(shí)器,并返回上次調(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);      // 進(jìn)程停在此處,直到收到定時(shí)器信號(hào)SIGALRM將進(jìn)程殺死
      13
      14        return 0;
      15}



      setitimer函數(shù)


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


      函數(shù)原型:

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


      返回值:

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


      參數(shù)說明:

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

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

      b. 用戶空間定時(shí):ITIMER_VIRTUAL。只計(jì)算進(jìn)程戰(zhàn)勝CPU的時(shí)間,即用戶空間時(shí)間。到達(dá)時(shí)間點(diǎn)后,發(fā)送SIGVTALRM信號(hào);

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

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


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


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


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


      例程:

      自己實(shí)現(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);      // 進(jìn)程停在此處,直到收到定時(shí)器信號(hào)SIGALRM將進(jìn)程殺死
      33
      34        return 0;
      35}


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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多