進程間通訊

複習:
進程建立
fork();

進程終止
exit(0)/return 0;

進程等待
wait()/waitpid(pid,NULL,0);

進程替換
exec函數族

------------------------
1.system()函數
system - execute a shell command
#include<stdlib.h>
int system(const char *command);
system - execute a shell command

system("ls -l");

---------------------
進程間通訊
1.基本概念
兩個/多個進程之間的數據交換/交流,叫作進程間通訊。

2.通訊方式
1.文件
2.信號
3.管道
4.共享內存
5.消息隊列
6.信號量
7.網絡編程
...
其中456三種通訊方式,稱爲XSI/IPC
(X/open system interface inter-process communication)
linux

3.中斷
中斷-表示暫時中止當前進程的執行轉而去執行新程序或處理意外狀況的過程,叫作中斷
中斷分爲軟件中斷和硬件中斷

4.信號的處理
1.信號的本質就是軟中斷,它能夠做爲進程間通訊的一種方式,更重要的是,信號是能夠中斷一個正常運行的程序,更多的被用來處理意外狀況。
2.信號的特色:
a.信號是異步的,進程不知道信號什麼時候到達
b.進程能夠處理信號,還能夠發送信號給指定的進程
c.每一個信號都有一個名字,而且使用SIG開頭。

3.基本命令
kill -l 查看系統所支持的全部信號
須要掌握的信號有:
ctrl + c 發送信號 2 SIGINT 默認處理方式終止進程
ctrl + \ 發送信號 3 SIGQUIT 默認處理方式終止進程
kill -9 發送信號 9 SIGKILL 默認處理方式終止進程shell

4.信號的分類
linux支持的信號範圍是1-64,不保證連續
unix支持的信號範圍是1-48
其中1-31之間的信號 叫不可靠信號,不支持排隊,信號可能丟失,也叫非實時信號
其中34-64之間的信號 叫可靠信號,支持排隊,也叫實時信號

5.信號的處理方式
1.默認處理 大多數信號的默認處理方式都是終止進程
2.忽略處理
3.自定義處理 只須要寫一個信號處理函數就能夠

注:
1.信號SIGKILL只能進行默認處理,不能忽略,也不能自定義處理
2.信號的發送受到用戶權限的影響,也就是每一個用戶只能給本身的進程發信號。root用戶能夠給全部的進程發信號。

3.信號0有特殊用途,自己不表明任何事件,也不會處理,用於測試用戶是否有權限發信號
kill -0 1


6.信號處理的實現步驟:
1.寫一個信號處理函數
2.用signal註冊信號處理方式

函數指針 signal(int 信號,函數指針);
這個函數指針的格式:
void (*func)(int);
功能:
當signal(信號,函數指針)執行完畢後,只要有信號來,系統就會調用這個函數指針所對應的函數。

第一個參數:信號名稱/數值(表示要處理哪個信號)
第二個參數:信號的處理方式:
SIG_DFL 默認處理
SIG_IGN 忽略處理
函數指針 自定義函數處理
返回值:
成功返回以前的處理方式,失敗返回SIG_ERR

練習:
設置對信號2進行自定義處理
信號3進行忽略處理
對信號9進行默認處理
使用fork建立子進程,打印子進程的PID,讓子進程無限循環,父進程直接結束
在另外一個終端使用kill命令給子進程發送上述3種信號,觀察處理結果。


結論:對於fork出來的子進程,徹底照搬父進程對信號的處理方式。


7.kill()函數

kill - send signal to a process
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
功能:主要用於給指定的進程發送指定的信號
pid:進程號(給哪個進程發送信號)
sig:信號值/信號名稱
返回值:成功返回0
失敗返回-1,errno被設置

8.raise()函數
int raise(int sig);
功能:主要用於給正在調用的進程發送參數指定的信號
返回值:成功返回0
失敗返回非0
9.alarm函數
unsigned int alarm(unsigned int seconds);
功能:主要用於根據參數 指定的秒數以後,發送SIGALRM信號
成功返回上一個鬧鐘沒來得及響的秒數,以前沒有鬧鐘則返回0
當參數使用0時,以前設置的鬧鐘所有取消


10.pause()函數
int pause(void);
用來等待一個信號的到來,會致使調用進程休眠,直到收到一個信號(被幹掉/執行信號處理函數)


編程

 

/*************************************************************************
> File Name: alarm.c
> Author: csgec
> Mail: longer.zhou@gmail.com
> Created Time: Tue 09 Aug 2016 04:42:07 PM CST
************************************************************************/網絡

#include<stdio.h>
#include<signal.h>
void sigHander(int signo)
{異步

if(signo == SIGALRM)
{
printf("REcv signal %d \n",signo);
}
}
int main()
{
signal(SIGALRM,sigHander);函數

int r = alarm(10);
printf("r = %d\n",r);
sleep(3);
r = alarm(10);
printf("r = %d\n",r);
while(1)
{

}測試

}unix

 

 

 

/*************************************************************************
> File Name: kill.c
> Author: csgec
> Mail: longer.zhou@gmail.com
> Created Time: Tue 09 Aug 2016 04:26:55 PM CST
************************************************************************/指針

#include<stdio.h>
#include<signal.h>
#include<unistd.h>
int main()
{
pid_t pid;
pid = fork();隊列

if(pid == 0)
{
while(1);
}
else if(pid > 0)
{
int signo;
scanf("%d",&signo);
kill(pid,signo);
system("ps -aux");
}

return 0;
}

 

 

 

/*************************************************************************
> File Name: pause.c
> Author: csgec
> Mail: longer.zhou@gmail.com
> Created Time: Tue 09 Aug 2016 04:52:51 PM CST
************************************************************************/

#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
void sigHander(int signo)
{
printf("Recv SIGALRM signal \n");
}
int main()
{
signal(SIGALRM,sigHander);
alarm(10);
while(1)
{
pause();
printf("hello world\n");
}
exit(0);
}

 

 

 

/*************************************************************************
> File Name: signal1.c
> Author: csgec
> Mail: longer.zhou@gmail.com
> Created Time: Tue 09 Aug 2016 03:11:35 PM CST
************************************************************************/

#include<stdio.h>#include<signal.h>void myfunc(int signo){ printf("Recv signal %d\n",signo); if(signo == SIGINT) { } if(signo == SIGUSR1) { }}int main(){ signal(SIGINT,myfunc); signal(SIGQUIT,SIG_IGN); signal(SIGKILL,myfunc); printf("信號處理程序1\n"); pid_t pid = fork(); if(pid == 0) { while(1); } printf("pid = %d\n",pid);}

相關文章
相關標籤/搜索