八_进程控制7+2 - 命令实现简析

本文介绍了shell环境下执行命令时的进程创建过程,通过fork和execl函数,子进程变为可执行程序。在没有wait()善后处理的情况下,子进程直接exit(),导致输出结果与命令行终端交互出现。分析了因文件描述符共享导致父子进程共用一个终端输出的现象。

shell 环境下执行一个命令的时候,其实就是 fork()产生了一个子进程(也是一个shell),子进程(也是一个shell)再 execl,子进程摇身一变,变成了我们需要执行的可执二进制程序,如 ls 等。而子进程在运行的时候,父进程在wait()等待善后子进程资源。

如 ls 命令,一定是 ls 命令,回车后 一定是 ls的结果先显示出来,然后命令行再弹出来

回顾: 求质数

#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>

#define LEFT 200
#define RIGHT 250

int main(void)
{
	int i,j,mark;
	pid_t pid;
	
	for(i = LEFT; i <= RIGHT; i++)
	{
		pid = fork();
		if(pid < 0)
		{
			fprintf(stderr,"fork() failed!\n");
			exit(1);
		}
		else if(pid == 0)//child
		{
			mark = 1;
			for(j = 2; j < i/2; j++)
			{
				if(i % j ==0)
					{
						mark = 0;
						break;
					}
			
			}

			if(mark)
				printf("%d is a primer\n",i);

			exit(0);//!!!
		}
		
	}
	exit(0);
}


mhr@ubuntu:~/Desktop/xitongbiancheng/test$ gcc wait.c 
mhr@ubuntu:~/Desktop/xitongbiancheng/test$ ./a.out 
mhr@ubuntu:~/Desktop/xitongbiancheng/test$ 211 is a primer
223 is a primer
227 is a primer
229 is a primer
233 is a primer
239 is a primer
241 is a primer
^C
mhr@ubuntu:~/Desktop/xitongbiancheng/test$ 

看运行结果发现,运行 ./a.out,一定是命令行先打印出来,然后才是输出结果。

shell 创建了一个子进程,子进程 execl() 摇身一变 变成了 a.out 在运行,而a.out中 没有 wait()善后处理,所以这个a.out fork() 之后 马上执行 exit()退出,然后当前的shell 作为 a.out的父进程,正在wait() 等待收尸,所以等 a.out一退出,shell 马上收尸完成,打印命令行结束。而此时的 a.out fork()出来的子进程 已经变成了僵死进程,还在运行输出。

那么问题来了:为什么此时子进程的显示结果 也显示在 当前命令行终端上面呢? 为什么不是单独开一个终端输出呢?即父子进程为什么会共用一个 terminal的信息?

因为 父进程的文件描述符表中的 的文件描述符信息 复制一份给了子进程,两个进程的文件描述符信息相同。即 标准输出对象是相同的,所以父子进程会共用一个 terminal 终端信息。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ma浩然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值