`

关于signal程序的一个思考——进程排队问题

阅读更多
linux中的信号是一种异步通信,所谓“异步”,就是指这个事件发生的时间是无法确定的,他有可能在任何时刻发生。

之所以把标题写成“进程排队问题”,是我对我要提到的问题的思考而已,如果有高人能否决我的观点,我诚心接受。

请看如下c程序:
#include <stdio.h>
#include <stdlib.h> //exit() is used
#include <string.h>
#include <signal.h>
#include <unistd.h>

int wait_mark = 1; //if == 0, exit pause and return

void stop(int signo) { 
	wait_mark = 0;
}

void waiting() { //to pause if wait_mark != 0
	while (wait_mark)
		sleep(1);
}

int main(int argc, char *argv[])
{
	pid_t pid1, pid2;

//	signal(SIGINT, stop);
	if (-1 == (pid1 = fork() ) ) {
		perror("fork error:");
		exit(-1);
	}

	if (pid1 > 0) {
		if (-1 == (pid2 = fork() ) ) {
			perror("fork error:");
			exit(-1);
		}
		else if (pid2 > 0) {
			signal(SIGINT, stop);
			waiting();
			kill(pid1, SIGUSR1);
			kill(pid2, SIGUSR2);
			wait(0);
			wait(0);
			lockf(1, 1, 0);
			printf("parent is now exiting...\n");
			lockf(1, 0, 0);
		}
		else if (pid2 == 0) {
			signal(SIGUSR2, stop);
			signal(SIGINT, SIG_IGN);
			waiting();
			lockf(1, 1, 0);
			printf("child 2 is now exiting ...\n");
			lockf(1, 0, 0);
			exit(0);
		}
	}
	else if (pid1 == 0) {
		signal(SIGUSR1, stop);
		signal(SIGINT, SIG_IGN);
		waiting();
		lockf(1, 1, 0);
		printf("child 1 is now exiting ...\n");
		lockf(1, 0, 0);
		exit(0);
	}

	return 0;
}




运行情况大多数是先打印child 1退出的信息,但极少数情况会出现先打印child 2退出的信息。请注意,父进程发信号的时候是先给child 1发出的,见相邻两句kill的顺序。
下面是我从虚拟机vmware6.4安装的ubuntu9.04上运行的结果(注意粗体字部分):

引用

canlynet@canlynet-desktop:~/vm_share$ gcc -o signal1 signal1.c
canlynet@canlynet-desktop:~/vm_share$ ./signal1
^Cchild 1 is now exiting ...
child 2 is now exiting ...
parent is now exiting...
canlynet@canlynet-desktop:~/vm_share$ ./signal1
^Cchild 1 is now exiting ...
child 2 is now exiting ...
parent is now exiting...
canlynet@canlynet-desktop:~/vm_share$ ./signal1
^Cchild 2 is now exiting ...
child 1 is now exiting ...
parent is now exiting...

canlynet@canlynet-desktop:~/vm_share$ ./signal1
^Cchild 1 is now exiting ...
child 2 is now exiting ...
parent is now exiting...
canlynet@canlynet-desktop:~/vm_share$ ./signal1
^Cchild 1 is now exiting ...
child 2 is now exiting ...
parent is now exiting...
canlynet@canlynet-desktop:~/vm_share$ ./signal1
^Cchild 1 is now exiting ...
child 2 is now exiting ...
parent is now exiting...
canlynet@canlynet-desktop:~/vm_share$ ./signal1
^Cchild 1 is now exiting ...
child 2 is now exiting ...
parent is now exiting...
canlynet@canlynet-desktop:~/vm_share$ ./signal1
^Cchild 1 is now exiting ...
child 2 is now exiting ...
parent is now exiting...
canlynet@canlynet-desktop:~/vm_share$ ./signal1
^Cchild 1 is now exiting ...
child 2 is now exiting ...
parent is now exiting...
canlynet@canlynet-desktop:~/vm_share$ ./signal1
^Cchild 1 is now exiting ...
child 2 is now exiting ...
parent is now exiting...
canlynet@canlynet-desktop:~/vm_share$ ./signal1
^Cchild 1 is now exiting ...
child 2 is now exiting ...
parent is now exiting...
canlynet@canlynet-desktop:~/vm_share$ ./signal1
^Cchild 1 is now exiting ...
child 2 is now exiting ...
parent is now exiting...
canlynet@canlynet-desktop:~/vm_share$ ./signal1
^Cchild 1 is now exiting ...
child 2 is now exiting ...
parent is now exiting...
canlynet@canlynet-desktop:~/vm_share$ ./signal1
^Cchild 1 is now exiting ...
child 2 is now exiting ...
parent is now exiting...



关于这个特殊出现的情况,我估计是父进程执行kill的时候速度是很快的,所以万一某一次child 2在系统调度时排列在child 1的后面了,就可能出现child 2先退出的打印语句。
也就是说:大多数情况下父进程执行kill的两句话对子进程1和子进程2来说是对等的,虽然接收到信号有时间先后,但逻辑上没有先后关系,除非父进程执行完一个kill后正好时间片到了或者被打断了。
0
0
分享到:
评论

相关推荐

    实验一 进程通信——管道和信号实验报告.doc

    如果在程序中使用系统调用lockf()来给每一个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。 要求:使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即DEL键)...

    (修改版)实现进程的软中断通信。要求:使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断

    使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上的中断信号(即按DEL键);当捕捉到中断信号后,父进程用系统调用Kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止: ...

    进程的创建编写一段程序,使用系统调用fork()创建两个子进程。当此程序运行时,

    进程的创建 编写一段程序,使用系统调用fork()创建两个子进程。当此程序运行时, ...让每一个进程在屏幕上显示一个字符:父进程显示“A”; 子进程分别显示字符“b”和“c”。试观察记录屏幕上的显示结果

    linux下的进程管理演示(c语言)

    当此程序运行时,在系统中有一个父进程和两个子进程活动。每个进程在屏幕上显示一个字符,记录屏幕上的显示结果,并分析原因。修改以编写的程序,将每个进程输出一个字符改为每个进程输出一句话。 进程的软中断通信...

    进程通信----软中断

    使用系统调用fork()创建两个子程序,再用系统调用signal()接收父进程从键盘上来的中断信号(即按Ctrl+c键);当有中断信号后,父进程用系统调用Kill()向两个子进程发出信号,子进程有信号后分别输出 Child ...

    操作系统=进程管理=实验报告

    当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示'a',子进程分别显示字符'b'和字符'c'。试观察记录屏幕上的显示结果,并分析原因。 2、修改上述程序,每一个...

    3操作系统实验.doc

    2、分析利用软中断通信实现进程同步的机理 实验指导 一、信号 1、信号的基本概念 每个信号都对应一个正整数常量(称为signal number,即信号编号。定义在系统头文件&lt;signal.h&gt;中),代表同一用户的诸进程之间传 送事先...

    Python基础——多进程及进程间通信

    文件中包含文件的拷贝方法,多进程的基础概念,相关函数的用法,队列的先进先出,共享内存等内容。

    操作系统实验进程的软中断通信

     编写一段程序,父进程创建一个子进程p1;并使子进程利用系统调用kill()向父进程发送信号,父进程得到信号后输出字符串“received p1 signal.” 。 4[实验要求]  (1)正确应用系统调用signal()建立进程与信号...

    一个进程池的服务器程序

    一个进程池的服务器程序 下面做了非常简单的http服务器,该服务器只能接收Get请求。 流程大概如下: 1,父进程listen,创建pipe(下面所有父子进程之间的通信都用该pipe) 2,父进程预fork n个子进程 3,各个子...

    进程管理 进程的软中断通信

    使用系统调用signal()让进程捕捉用alarm函数设置时钟的时间段终止时产生的信号,当捕捉到该信号后,父进程使用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后分别输出子进程被杀死信息后终止,父进程...

    signal-exit, 当你想激发一个事件无论进程如何退出.zip

    signal-exit, 当你想激发一个事件无论进程如何退出 信号退出 无论进程如何退出,都要激发事件:到达执行结束。显式地调用 process.exit(code) 。叫 process.kill(pid, sig) 。接收来自进程外部的致命信号使用 signal

    操作系统课程设计-信号通信与进程控制

    (2)进程的控制:在程序中使用系统调用lockf()来给每一个进程加锁,实现进程之间的互斥。 (3)进程通信:①软中断通信;②在程序中使用语句signal(SIGINT,SIG_IGN)和signal(SIGQUIT,SIG_IGN),观察执行结果,并分析...

    操作系统课程设计——模拟生产者与消费者(java)

    在多道程序环境下,进程同步问题十分重要,通过解决“生产者-消费者”问题,可以帮助我们更好的理解进程同步的概念及实现方法。掌握线程创建和终止的方法,加深对线程和进程概念的理解,会用同步与互斥方法实现线程...

    C++程序设计实践项目——学生信息管理系统,基于Qt+MySQL.zip

    用c++/qt写的项目,可供自己学习,项目都经测试过,真实可靠,请放心使用。Qt支持 Windows、Linux/Unix、Mac OS X、Android、BlackBerry、QNX等...在下层发出一个 Signal,这时上层与其想关联的 Slot 函数就会响应。

    2.信号通信与进程控制

    l 进程的创建:编写一段程序 使用系统调用fork 创建两个或多个子进程 当此程序运行时 在系统中有一个父进程和其余为子进程活动 2 进程的控制:在程序中使用系统调用lockf 来给每一个进程加锁 实现进程之间的互斥 ...

    进程管理实验(操作系统)

    当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。试观察记录屏幕上的显示结果,并分析原因。(2) 进程的...

    对Python信号处理模块signal详解

    Python中对信号处理的模块主要是使用signal模块,但signal主要是针对Unix系统,所以在Windows平台上Python不能很好的发挥信号...定义了一个信号处理函数signal_handler(),用来处理程序接收到信号时执行的操作 一段循

    linux进程间通信——信号机制

    对linux信号机制的详细阐述,包括signal,sigaction等函数的用法,并配以实例,通俗易懂,适合初学者阅读。。。

    进程的管道通信实验

    /*创建一个管道*/ while ((pid1=fork( ))==-1); if(pid1= =0) { lockf(fd[1],1,0); sprintf(outpipe,"child 1 process is sending message!"); /*把串放入数组outpipe中*/ write(fd[1],outpipe,50); /*向管道写...

Global site tag (gtag.js) - Google Analytics