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


  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值