1. 程式人生 > >signal訊號

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;
}