`

关于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

    在成功创建子进程后,fork()返回一个整数值,若在父进程中返回的是子进程的PID,在子进程中返回0。实验中,父进程和两个子进程分别输出特定的信息,以此验证进程的创建。 【进程控制与互斥】 利用lockf()系统调用...

    Linux下C语言编程——进程通信

    信号量的概念源于PV操作,即P(Wait)操作和V(Signal)操作,它们都是原子操作,确保在同一时间只有一个进程访问共享资源。在Linux中,仅支持无名信号量。无名信号量通过以下函数进行操作: - `sem_init()`:初始...

    进程间同步互斥问题——银行柜员服务问题1

    该问题模拟了一个银行环境,其中n个柜员为顾客提供服务。为了解决这个问题,我们需要用到P、V操作(即wait和signal操作),这是荷兰计算机科学家Dijkstra提出的信号量机制,用于解决资源竞争和同步问题。 【信号量...

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

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

    进程通信----软中断

    在计算机科学领域,进程间的通信(IPC)是多进程或线程程序设计中的一个关键环节,它允许不同的进程间共享数据、同步操作以及相互协作。软中断作为一种特殊的进程间通信机制,在本示例中被用来实现父子进程之间的...

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

    ### 实验一 进程通信——管道和信号实验报告 #### 实验背景及目标 本实验旨在通过实际操作深入理解进程通信的相关概念和技术,特别是管道和信号这两种进程间通信方式。实验目标具体包括: 1. **加深对进程概念的...

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

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

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

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

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

    其中,信号(Signal)是一种轻量级、异步的通信方式,它允许一个进程向另一个进程发送一个通知,表明某个事件已经发生或者请求进程执行特定的操作。本篇文章将深入探讨Linux信号机制,包括其基本概念、主要函数如`...

    操作系统实验1 进程控制

    操作系统实验1 进程控制是计算机科学领域中的一个重要实践环节,它主要涉及到操作系统核心功能之一——进程管理。在这个实验中,我们将使用C++编程语言来模拟和实现进程控制的基本概念和机制,这对于理解和掌握操作...

    进程同步与互斥

    举个例子,假设有一个生产者-消费者问题,生产者进程填充缓冲区,而消费者进程消费缓冲区中的数据。我们可以定义一个共享的缓冲区和一个信号量来保护缓冲区,同时使用条件变量来通知消费者数据已准备好。生产者在填...

    fork 两个子进程 及其进程控制

    `fork()`是Unix/Linux系统中的一个系统调用,用于创建一个新的进程——子进程。当父进程调用`fork()`时,操作系统会复制父进程的所有资源(如内存空间、文件描述符等)给新创建的子进程,形成一份完全独立的副本。...

    3操作系统实验.doc

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

    操作系统进程同步问题(吃水果问题)

    操作系统中的进程同步问题是一个复杂而重要的主题,它涉及到多个并发执行的进程之间的协调与通信,以确保系统的正确性和效率。吃水果问题是一个经典的进程同步问题实例,它通常用于教学目的,帮助学生理解如何使用...

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

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

    进程的同步与互斥习题(含参考答案).doc

    2. 一个输入进程向一个缓冲区中输入数据,另一个输出进程从缓冲区中取出数据输出。 这是一个典型的生产者-消费者问题。为了解决这个问题,可以使用信号量机制,设置两个信号量:empty 和 full。empty 信号量用于...

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

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

Global site tag (gtag.js) - Google Analytics