#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/
/*
============================================================================
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; }