操作系统-关于fork&父进程&子进程

版权声明:醋姑娘 https://blog.csdn.net/weixin_37023469/article/details/82996092

前言

这学期在学操作系统,目前感觉还是挺有意思的。

操作系统老师:“鼓励你们大开脑洞多试试,会有各种奇异的结果,但是最后居然都能解释出来。”

本文是根据课上讲解+自行实践写的。

测试环境:Ubuntu

正文

关于fork()的3种返回值

  • 这里提到的fork和下面程序中使用的fork()是一个C语言库函数,不是系统调用级别的fork();它根据不同的情况会返回3种类型的值。(而系统调用级别的fork只返回一种值:那就是创建出来的子进程的pid。)
    1. 在父进程中,返回创建的子进程的pid
    2. 在子进程中,返回0
    3. 出错,返回负值

下面程序的if分支是对这个知识点的运用。

#include <stdio.h>
#include <unistd.h>

int main(){

	pid_t pid;
	pid = fork();  //创建子进程
	
	if(pid==0){
		printf("child process\n");
	}
	else if (pid>0){
		printf("parent process\n");
	}
	else{
		//error 这里不作处理
	}	

}

输出结果是:
parent process
child process
(不同操作系统中可能顺序不一样?因为父进程和子进程可以并发,执行顺序由操作系统调度策略决定?——不是特别确定)

关于缓冲区

  • 上课的时候老师提到了一个例子,让我们回去自己试试
#include <stdio.h>
#include <unistd.h>

int main(){

	pid_t pid;
	
	//第一种
	printf("start...");
	//第二种
	//printf("start...\n");
	
	pid = fork();
	
	if(pid==0){
		printf("child process\n");
	}
	else if (pid>0){
		printf("parent process\n");
	}
	else{
		//error 这里不作处理
	}	

}

可以看到我们在fork()调用前写了一局printf,两种情况唯一的区别就是多了个’\n’。

  • 输出结果:
    1. 第一种:
      start…parent process
      start…child process
    2. 第二种:
      start…
      parent process
      child process

看到这个结果我就觉得可能是’\n’能刷新/清除缓冲区之类的原因吧。然后问了下老师。

  • 我:pcb中是否存在类似输出缓冲区的信息,而换行可以刷新/清空缓冲区?所以执行fork()时,"start…"还在缓冲区没有真正地被输出在显示器上,就被复制到子进程的pcb中的缓冲区去了。
  • 老师:如果不强制清除缓冲区,想当于子进程不仅copy了父进程的内存、PCB,还copy了缓冲区的内容。\n 或者flush都是强制清除缓冲区,所以加\n就是清除之后再执行下一条指令。如果不加\n,提交到缓冲区就接着执行下一条指令了。

关于wait()的机制

  • 经过测试,Ubuntu下:当父进程调用wait()函数时,是从调用的那一刻起,CPU就不再执行父进程了,父进程进入waiting(阻塞)状态,等待合作进程(子进程)的消息,直到子进程完全结束,父进程才会变成ready(就绪)状态。
  • 因为只在Ubuntu和Mac os上测试了下,在别的系统中还有一种可能(虽然并未找到这样的系统,因为根本没有去试):CPU还是会执行父进程,只是每次执行的时候都因为fork()、wait()返回值之类的原因在一直停留在wait(),无法执行下面的语句,造成从表面上看好像没有执行的假象。

猜你喜欢

转载自blog.csdn.net/weixin_37023469/article/details/82996092