厦门园网站忱建设,ASP做购物网站视频,做怎么样的自己的网站,免费在线建站目录 一、前言
二、fork()函数
2.1 fork()函数的基本概念
2.2 问题一的解答
2.3 问题二的解答
2.4 问题三的解答
2.5 问题四的解答
2.6 问题五的解答 一、前言 在上节内容中我们已经学会了使用我们的getpid()和我们的getppid()去查看我们进程的pid#xff0c;并且学习到…目录 一、前言
二、fork()函数
2.1 fork()函数的基本概念
2.2 问题一的解答
2.3 问题二的解答
2.4 问题三的解答
2.5 问题四的解答
2.6 问题五的解答 一、前言 在上节内容中我们已经学会了使用我们的getpid()和我们的getppid()去查看我们进程的pid并且学习到了两种查看进程的方式在我们的正文开始之前我先对上文的一些内容做一些补充。 在第二种查看进程的方式中我们看到一个进程的详细信息 即上图的右半部分这里我们主要对其中的 cwd 和 exe 进行说明。 我们经常会遇到一个概念叫做文件的当前目录那什么是当前目录呢这是什么意思呢子在进程中 cwd 就指向该进程的当前目录其实就是在默认情况下进程启动所在的路径就是当前的工作目录。 那 exe 又是什么呢exe 指向的是可执行程序的位置。 在Linux中我们可通过指令来修改当前的工作目录 chdir 路径 修改工作目录 二、fork()函数
2.1 fork()函数的基本概念提出问题 这里有一个问题那就是如何去创建一个进程呢最简单的方法就是执行我们的可执行程序系统就会生成一个进程。我们还可以通过fork()这个函数在代码去主动去创建进程。
我们可以先用man指令查询一下这个函数 简单来说fork()函数的作用就是创建一个当前进程的一个子进程。那我们要怎么理解去创建一个进程这样的一个概念呢 创建一个进程其实就是系统申请内存保存我们当前的可执行程序生成其对应的一个PCB并将该可执行程序及其PCB加入到我们的进程列表中。 接下来就让我们先来看看fork()创建的进程有和特征。 先写一段这样的代码我们去观测一下该子进程的信息至于为什么要这样写我们等会再说先跑起来看看。 我们会发现确实出现了两个进程且其中一个进程的ppid是我们一个进程的pid。 很明显在我们的红色框框内第一个进程跟我们上节所讲的进程差不多其父进程会是我们的命令行解释器。而这个第二个进程就应该是我们fork()函数所创建出来的子进程了。那我们再来看一段代码。 再来看看这段代码的运行结果。 不难发现听音乐和下电影在同时运行可是我们printf函数明明就只执行了一次为什么会输出两个不同的值难道是我们的子进程继承了我们父进程的代码吗就算是继承我父进程的代码那我的fork()为什么会有两个返回值呢这也太不符合我们之前所学了。那我们不妨把我们所有的问题全部抛出了一个一个解决。 问题 fork()函数干了什么事我们为什么要使用它为什么fork()函数会有两个不同的返回值为什么fork()的返回值会给父进程返回子进程的pid而给子进程返回0fork之后子进程和父进程谁先执行如何去理解一个变量却又不同的返回值 2.2 问题一的解答 刚刚我们有讲fork()函数的作用是创建了一个子进程那这个子进程有什么用呢 我们创建子进程主要为了使用其有两个返回值的特性来帮助我们实现多任务并行运行这一场景。举个例子比如上文我们想边下载电影边听音乐的场景。可是我们新建出来的子进程按道理来说是不会有代码的那其是如何满足我们的需求的呢 所以在fork之后我们的父进程和我们的子进程会执行一样的代码那这里可能就有人会问了那fork之前的代码呢子进程就不执行了吗 是的确实是不执行了但是不是因为其看不到父进程的所有代码而是子进程同样继承了父进程的寄存器。
2.3 问题二的解答 问题又来了为什么fork()会返回两个不同的值呢 在上文我们有提到一个进程是怎么被创建出来的即当其可执行程序和PCB被加入到进程队列时该进程就已经被创建成功了那这个时候fork()函数有没有结束呢 没有只能说其创建进程的任务完成了但其还又一个语句没有执行呢什么呢那就是return。再回答第一个问题的时候我们就有提到子进程会继承父进程的寄存器那么此时寄存器是不是指向的是return语句呢 很显然是的那么父进程返回一个值子进程返回一个值不就有两个返回值了吗 放张图加深一下理解。
2.4 问题三的解答
为什么fork()的返回值会给父进程返回子进程的pid而给子进程返回0呢 这是因为父进程它很有可能不只有一个子进程那其要是想对它的子进程进行管理该怎么做呢那肯定是要根据其子进程的标识符呀那么进程的标识符是什么呢就是其pid。给自己的返回自己的pid没什么意义所以fork就给子进程返回0。
2.5 问题四的解答 创建完成子进程这仅仅是一个开始创建完成子进程之后系统的其他进程父进程子进程都等着被系统调度执行。当父子进程的PCB都被创建且都在运行队列操作系统会把其将要执行的代码放入一个队列中进行排队这个队列就叫运行队列中排队的时候哪个进程先被调度那个进程就先被执行。但是这个调度顺序是不确定的由操作系统本身决定由各自PCB中的调度信息时间片、优先级等 调度器算法共同决定的。
2.6 问题五的解答
为什么有两个返回值我们已经知道了但是为什么这两个返回值不相同呢 这里就要提到进程的独立性其独立性首先就体现在各自的PCB是不会相互影响的。虽然父子进程共享代码但是代码是只读的无法被修改。但是数据却是可以被修改的如果存在一个全局变量我父进程需要根据这个全局变量作为判断条件而我的子进程却会修改这个全局变量那这不就影响到了我们的父进程了吗所以数据每个进程都得想办法私有一份怎么私有都拷贝下来吗如果代码量很大的话拷贝的代价就有点大了而我们的操作系统是不会允许这样降低效率的事情发生的那么我们该怎么办呢 这里主要是使用到了写时拷贝的方法父子进程还是一样的共享代码只有当自己要修改其中的某个变量时才把这个变量拷贝过来以达到不会相互影响的状态。