1. 程式人生 > >Linux學習之程序通訊(三)

Linux學習之程序通訊(三)

言之者無罪,聞之者足以戒。 ——《詩序》

二、訊號的接收

接收訊號的程序,需要的條件:要想使接收的程序能收到訊號,這個程序就不能結束

接收訊號的函式:sleep()、while(1)、pause()

sleep()函式使程序進入睡眠狀態(S)

pause()函式使程序進入睡眠狀態(S)

while(1)函式使程序一直在執行(R狀態)

sleep()和while(1)都非常簡單,上面的程式我們都已經使用過了,現在來說一下pause()函式,其實pause()函式也很簡單。它沒有入口引數,返回值也很簡單,下面我們來看一下:

所需標頭檔案

#include <unistd.h>

函式原型

int pause(void);

函式返回值

成功:0,出錯:-1

   下面給出關於pause函式的程式:

#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
int main()
{
        int i=0;
        printf("pause befor\n");
        pause();
        printf("pause after\n");
        return 0;
}

三、訊號的處理

收到訊號的程序,應該怎樣處理?處理的方式有哪些?

(1)程序的預設處理方式(核心為使用者程序設定的預設處理方式)

A:忽略

B:終止程序

C:暫停

(2)自己的處理方式:

自己處理訊號的方法告訴核心,這樣你的程序收到了這個訊號就會採用你自己的處理方式

1、signal函式:

void (*signal(int signum, void (*handler)(int)))(int);

signal函式有兩個引數:

第一個引數:是一個整形變數(訊號值)

第二個引數:是一個函式指標,是我們自己寫的處理函式

返回值:是一個函式指標

所需標頭檔案

#include <signal.h>

函式原型

void (*signal(int signum, void (*handler)(int)))(int);

函式傳入值

signum:指定訊號

handler

SIG_IGN:忽略該訊號。

SIG_DFL:採用系統預設方式處理訊號。

自定義的訊號處理函式指標

函式返回值

成功:設定之前的訊號處理方式

出錯:-1

下面給出一段程式:

include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
void myfun(int signum)
{
        int i=0;
        while(i < 6)
        {
                printf("process signal signum=%d\n",signum);
                sleep(1);
                i++;
        }
        return;//return main
}
int main()
{
        int i=0;
        signal(14,myfun);
        printf("pause befor\n");
        alarm(8);
        printf("pause after\n");
        while(i < 20)
        {
                printf("process working time is %d\n",i);
                i++;
                sleep(1);
        }
        return 0;
}

上面我們說了handler引數形式有三種,第三種我們已經演示過了下面演示一下第一種和第二種:

第一種程式程式碼:

#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
void myfun(int signum)
{
        int i=0;
        while(i < 6)
        {
                printf("process signal signum=%d\n",signum);
                sleep(1);
                i++;
        }
        return;//return main
}
int main()
{
        int i=0;
        signal(14,myfun);
        printf("pause befor\n");
        alarm(8);
        printf("pause after\n");
        signal(14,SIG_IGN);
        while(i < 20)
        {
                printf("process working time is %d\n",i);
                i++;
                sleep(1);
        }
        return 0;
}

第二種程式程式碼:  

#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
void myfun(int signum)
{
        int i=0;
        while(i < 6)
        {
                printf("process signal signum=%d\n",signum);
                sleep(1);
                i++;
        }
        return;//return main
}
int main()
{
        int i=0;
        signal(14,myfun);
        printf("pause befor\n");
        alarm(8);
        printf("pause after\n");
        signal(14,SIG_IGN);
        signal(14,SIG_DFL);
        while(i < 20)
        {
                printf("process working time is %d\n",i);
                i++;
                sleep(1);
        }
        return 0;
}

下面我們寫一段程式來實現一下的功能:

(1)子程序sleep(10)之後向父程序傳送一個訊號

(2)父程序接收訊號之後,按照自己定義的方式處理訊號

(3)再sleep(10)之後再一次向父程序傳送一個訊號

(4)父程序接收訊號之後,按照自己定義的第二種方式處理訊號

#include "stdio.h"
#include "sys/types.h"
#include "signal.h"
#include "stdio.h"
#include "stdlib.h"
void myfun(int signum)
{
        int i=0;
        while(i < 5)
        {
                printf("receive signum=%d,i=%d\n",signum,i);
                sleep(1);
                i++;
        }
        return ;
}
void myfun1(int signum)
{
        printf("receive signum=%d\n",signum);
        wait(NULL);
        return;
}
int main()
{
        pid_t pid;
        pid=fork();
        if(pid >0)
        {
                int i=0;
                signal(10,myfun);
                signal(17,myfun1);
                while(1)
                {
                        printf("parent process things ,i=%d\n",i);
                        sleep(1);
                        i++;
                }
        }
        if(pid == 0)
        {
                sleep(10);
                kill(getppid(),10);
                sleep(10);
                exit(0);
        }
        return 0;
}

到這為止,關於訊號通訊方面的知識就已經說完了。