signal訊號
#include <stdio.h> #include <stdlib.h> #include<signal.h> #include<sys/types.h> void func() { puts("hello"); } int main(void) { signal(SIGALRM,func);//當接受到ALARM訊號時就做func函式裡面做的事情父 alarm(4);//設定4秒的腦中 pause();//產生中斷,去執行func函式 //如果把前面的signal(SIGINT,SIGDEF);去掉,則該程式不會有任何輸出,因為alarm訊號的預設處理方式 就是退出 puts("I am going on"); // signal(SIGINT,SIG_IGN);//Y一旦遇到SIGINT這個訊號,就將其忽略掉,按 ctrl+c是不會干擾的,要想退出程序可以ctrl+z // signal(SIGINT,func);//一旦遇到終端,就執行func這個函式 // signal(SIGINT,SIG_DFL);//這個是不產生任何的影響的 while(1); return EXIT_SUCCESS; }
1.通過訊號量通訊:
/* ============================================================================ Name : connectBySignal.c Author : Version : Copyright : Your copyright notice Description : Hello World in C, Ansi-style ============================================================================ */ /* * 1.子程序繼承父程序之前執行的一切狀態,包括對於訊號處理方式的修改。 * 2.ctrl+c非同步事件的產生,導致核心發出的sigint訊號會發給前臺程序組*/ #include <stdio.h> #include <stdlib.h> #include<signal.h> #include<unistd.h> #include<sys/wait.h> int wait_mark; //系統呼叫signal()讓父程序捕捉鍵盤上的中斷訊號,捕捉後,父程序用系統呼叫用kill()向兩個子程序發出訊號,然後子程序各自輸出 void waiting() { while(wait_mark!=0); } void stop() { wait_mark=0; } int main(void) { int p1,p2; signal(SIGINT,stop);//接受到ctrl+c訊號,stop111111111111111 while((p1=fork())==-1); if(p1>0) { //signal(SIGINT,stop);//222222222222222 while((p2=fork())==-1); if(p2>0) { //signal(SIGINT,stop);//3333333333333333333 wait_mark=1; waiting(); kill(p1,10); kill(p2,12); wait(NULL); wait(NULL); puts("father exits"); exit(0); } else if(p2==0) { wait_mark=1; signal(12,stop); waiting(); lockf(1,1,0);//第一個引數的標誌1是標準輸出 printf("child2 process is killed by father\n"); lockf(1,0,0); exit(0); } } else { wait_mark=1; signal(10,stop); waiting(); lockf(1,1,0); puts("child1 process is killed buy father"); lockf(1,0,0); exit(0); } return EXIT_SUCCESS; } /*對於三種不同的安置情況對應的結果及其分析 * 1.首先是通過signal(SIGINT,stop);來設定當遇到ctrl+c訊號時就用stop來處理 * 之後建立了一個子程序,在父程序裡面再建立一個子程序,在父程序中,分別給兩個子程序通過kill傳送usr1,和usr2資訊,對應數字為10,12 * 然後在子程序1裡面,等待標誌為1,並且設定當受到usr1訊號是用終止來處理,之後等待觸發ctrl+c事件,觸發後從waiting事件走出來,列印自己的資訊,被父程序殺死 * 程序2同理 * child1 process is killed buy father child2 process is killed by father father exits * 2.這個是在建立子程序之後的設定signal(SIGINT,stop);,所以子程序1就不會繼承到這個訊號,一直就處於等待接受usr1訊號,但是如果接收到ctrl+c,就自動中止 * 而子程序2還是可以接受的 * child2 process is killed by father * father exits *3.兩個子程序都沒能接受到usr1或usr2,遇到ctrl+c訊號後直接退出 *father exits/
2.通過訊號量通訊
/*
============================================================================
Name : connectBySignal2.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
//對上一個程式進行修改,增加語句signal(SIGINT,SIG_INT)和語句signal(SIGQUIT,SIG_IGN)
#include <stdio.h>
#include <stdlib.h>
#include<signal.h>
#include<unistd.h>
#include<sys/wait.h>
int pid1,pid2;
//一個程序中多次呼叫signal函式,以最後一次的設定為準
void Initdelete()
{
kill(pid1,10);//給兩個子程序分別傳送usr1和usr2訊號
kill(pid2,12);
}
void Init1()
{
puts("child1 process is killed by father");
exit(1);
}
void Init2()
{
puts("child2 process is killed by father");
exit(0);
}
int main(void) {
signal(SIGINT,SIG_IGN);//當遇到中斷時,響應忽略,如果這一步捨去了,就不能保證子程序在遇到ctrl+c訊號時會處理,而時會按預設方式直接終止
signal(SIGQUIT,SIG_IGN);
pid1=fork();
if(pid1>0)
{
pid2=fork();//建立第一個子程序
if(pid2>0)
{
signal(SIGINT,Initdelete);//當出現ctrl+c訊號的時候,用Initdelete來處理
waitpid(-1,NULL,0);//等待任何子程序中斷或者結束
waitpid(-1,NULL,0);//等待任何子程序中斷或者結束
puts("father exit");
exit(0);
}
else
{
signal(12,Init2);
pause();
exit(0);
}
}
else if(pid1==0)
{
signal(10,Init1);//獲得usr1訊號用,用Init來處理這個函式
pause();//應該是在沒有訊號時掛起,當有訊號時喚醒執行init1
exit(0);
}
return EXIT_SUCCESS;
}
3.司機售票員問題:
建立子程序代表售票員,父程序代表司機,同步過程如下:
售貨員捕捉SIGINT(代表開車),發SIGUSR1給司機,司機列印:let us go go go
售票員捕捉SIFQUIT(代表開車),發SIGUSR2給司機,司機:top the bus
司機捕捉SIGTSTP(代表車到總站),發SIGUSR1給售票員,售票員列印:please get off the bus
/*
============================================================================
Name : busConnect.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include<sys/wait.h>
#include<signal.h>
#include<unistd.h>
int pid1,pid2;
void Init1()
{
puts("let us go go go");
}
void Init2()
{
puts("stop the bus");
}
void Init3()
{
puts("please get off the bus");
}
void Init4()
{
kill(pid1,10);
}
void Init5()
{
int k=getppid();
kill(k,10);
}
void Init6()
{
int j=getppid();
kill(j,12);
}
int main(void)
{
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
signal(SIGTSTP,SIG_IGN);
pid1=fork();
if(pid1>0)//父程序
{
signal(10,Init1);
signal(12,Init2);
signal(SIGTSTP,Init4);
while(1);
exit(0);
}
else if(pid1==0)
{
signal(SIGINT,Init5);
signal(SIGQUIT,Init6);
signal(10,Init3);
while(1);
exit(0);
}
else
{
puts("wrong");
}
return EXIT_SUCCESS;
}