程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 一起talk C語言例子(第八十五回:C語言實例--使用信號進行進程間通信二)

一起talk C語言例子(第八十五回:C語言實例--使用信號進行進程間通信二)

編輯:關於C語言

一起talk C語言例子(第八十五回:C語言實例--使用信號進行進程間通信二)



各位看官們,大家好,上一回中咱們說的是使用信號進行進程間通信的例子,這一回咱們接著上一回的內容,繼續說該例子。閒話休提,言歸正轉。讓我們一起talk C栗子吧!

我們在上一回中舉了使用信號進行進程間通信的例子,在該例子中,我們通過終端發出信號,當進程收到該信號後讓它執行系統對信號定義的默認動作。這一回,我們再來舉一個使用信號進行進程間通信的例子,不過,我們發送和處理信號的方式和上一回的例子不一樣。在接下來的例子中,我們在一個進程中使用kill產生信號,在另外一個進程中接收並且按照自己的方式處理接收到的信號

在例子中我們使用kill函數給其它進程發送信號,下面是kill函數的原型

int kill(pid_t pid, int signo);
第一個參數pid表示進程的PID,kill函數將把信號發送給PID與其參數相同的進程; 第二個參數表示信號。該參數表示kill函數發送的信號值。 如果kill成功發送信號,那麼返回0,否則返回-1.

在例子中我們使用signal函數設置接收到信號後的處理方式,下面是signal函數的原型

void (*signal(int signo, void (*func) (int))) (int)

大家看著這個函數是不是覺得有點亂?先別慌,我們慢慢對它進行分析。

這個函數名叫signal,它用來配置信號處理函數,通俗點說,它就是為某個信號分配一個信號處理函數。它有兩個參數:

一個參數是signo,表示信號值; 另外一個參數是一個名叫func的函數指針,它表示信號處理函數。 也就是說進程接收到signo表示的信號後會使用該函數來處理信號。 參數中的func是一個函數指針,它指向的函數包含一個int類型的參數,表示信號值,該函數返回void。 最後,我們說一下signal函數的返回值,它返回一個函數,該函數就是func指向的信號處理函數。

接下來,我們通過具體的代碼來說明它們的用法

#include
#include
#include

void sig_receive(int signo)
{
    printf("received signal :%d \n",signo);
}

int main()
{
    pid_t pid;
    int pid_res;
    int stat_value;

    pid = fork();

    if(pid > 0)
    {
        printf("PID: %d -> Father Process send signal\n",getpid());
        kill(pid,SIGALRM);   //發送信號
    }
    else if(pid == 0)
    {
        signal(SIGALRM,sig_receive);  //配置信號處理函數
        printf("PID: %d -> Son Process receive signal \n",getpid());
    }
    else
    {
        printf("Create process failed \n");
        return 1;
    }

    pid_res = wait(&stat_value);

    if(pid_res > 0)
    {
        printf("Son process finished: PID = %d \n",pid_res);
    }

    return 0;
}

從上面的代碼中可以看到,我們在父進程中使用kill函數發送信號,然後在子進程中使用signal函數配置信號處理函數,當子進程收到信號後,信號處理函數就會對該信號進行處理。

看官們,正文中就不寫代碼了,詳細的代碼放到了我的資源中,大家可以點擊這裡下載使用。

下面是程序的運行結果,請大家參考

PID: 3208 -> Father Process send signal      //父進程發送信號
received signal :14                          //信號處理函數在處理信號
PID: 3209 -> Son Process receive signal      //子進程收到信號
Son process finished: PID = 3209             //子進程結束,父進程也結束    

看官們,從程序的結果中可以看出,父進程發出信號後,子進程收到了信號,並且進行了處理。這說明我們通過信號在兩個進程之間進行了通信

看官們,有個小的細節不知道大家有沒有發現:程序運行結果中先是執行信號處理函數中的內容,然後才執行子進程中的內容。如果我們把執行的順序調換一下會有什麼現象呢?

把下面這兩行代碼的執行順序調換一下,也是說把printf語句放在signal配置語句的前面。

        signal(SIGALRM,sig_receive);  //配置信號處理函數
        printf("PID: %d -> Son Process receive signal \n",getpid());

重新編譯並且運行程序後,得到以下運行結果

PID: 2611 -> Father Process send signal  //父進程發送信號
Son process finished: PID = 2612         //子進程結束,父進程也結束     

從上面的結果中以可以看到,子進程不但沒有收到信號,而且沒有執行。這是什麼原因呢?那是因為父進程發信號的時候子進程可能被阻塞,所以沒有執行。這也是signal函數缺點。

signal函數是早期Unix系統提供的函數,現在的新系統中已經使用sigaction函數取代它,不過在一些老的程序中還是能看到它的身影。下一回中,我們將介紹sigcation函數相關的內容。

各位看官,關於使用信號進行進程間通信的例子咱們就說到這裡。欲知後面還有什麼例子,且聽下回分解 。


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