操作系统实验-进程控制
操作系统实验报告进程管理

操作系统实验报告进程管理操作系统实验报告:进程管理引言操作系统是计算机系统中的核心软件,负责管理计算机的硬件资源和提供用户与计算机之间的接口。
进程管理是操作系统的重要功能之一,它负责对计算机中运行的各个进程进行管理和调度,以保证系统的高效运行。
本实验报告将介绍进程管理的基本概念、原理和实验结果。
一、进程管理的基本概念1. 进程与线程进程是计算机中正在运行的程序的实例,它拥有独立的内存空间和执行环境。
线程是进程中的一个执行单元,多个线程可以共享同一个进程的资源。
进程和线程是操作系统中最基本的执行单位。
2. 进程状态进程在运行过程中会经历不同的状态,常见的进程状态包括就绪、运行和阻塞。
就绪状态表示进程已经准备好执行,但还没有得到处理器的分配;运行状态表示进程正在执行;阻塞状态表示进程由于某些原因无法继续执行,需要等待某些事件的发生。
3. 进程调度进程调度是操作系统中的一个重要任务,它决定了哪个进程应该获得处理器的使用权。
常见的调度算法包括先来先服务(FCFS)、最短作业优先(SJF)和时间片轮转等。
二、进程管理的原理1. 进程控制块(PCB)PCB是操作系统中用于管理进程的数据结构,它包含了进程的各种属性和状态信息,如进程标识符、程序计数器、寄存器值等。
通过PCB,操作系统可以对进程进行管理和控制。
2. 进程创建与撤销进程的创建是指操作系统根据用户的请求创建一个新的进程。
进程的撤销是指操作系统根据某种条件或用户的请求终止一个正在运行的进程。
进程的创建和撤销是操作系统中的基本操作之一。
3. 进程同步与通信多个进程之间可能需要进行同步和通信,以实现数据共享和协作。
常见的进程同步与通信机制包括互斥锁、信号量和管道等。
三、实验结果与分析在本次实验中,我们使用了一个简单的进程管理模拟程序,模拟了进程的创建、撤销和调度过程。
通过该程序,我们可以观察到不同调度算法对系统性能的影响。
实验结果显示,先来先服务(FCFS)调度算法在一些情况下可能导致长作业等待时间过长,影响系统的响应速度。
操作系统实验报告

篇一:操作系统实验报告完全版《计算机操作系统》实验报告班级:姓名:学号:实验一进程控制与描述一、实验目的通过对windows 2000编程,进一步熟悉操作系统的基本概念,较好地理解windows 2000的结构。
通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解windows 2000中进程的“一生”。
二、实验环境硬件环境:计算机一台,局域网环境;软件环境:windows 2000 professional、visual c++6.0企业版。
三、实验内容和步骤第一部分:程序1-1windows 2000 的gui 应用程序windows 2000 professional下的gui应用程序,使用visual c++编译器创建一个gui应用程序,代码中包括了winmain()方法,该方法gui类型的应用程序的标准入口点。
:: messagebox( null, “hello, windows 2000” , “greetings”,mb_ok) ;/* hinstance */ , /* hprevinstance */, /* lpcmdline */, /* ncmdshow */ )return(0) ; }在程序1-1的gui应用程序中,首先需要windows.h头文件,以便获得传送给winmain() 和messagebox() api函数的数据类型定义。
接着的pragma指令指示编译器/连接器找到user32.lib库文件并将其与产生的exe文件连接起来。
这样就可以运行简单的命令行命令cl msgbox.cpp来创建这一应用程序,如果没有pragma指令,则messagebox() api函数就成为未定义的了。
这一指令是visual studio c++ 编译器特有的。
接下来是winmain() 方法。
其中有四个由实际的低级入口点传递来的参数。
操作系统实验1--进程管理

设计一个有N个进程的进程调度程序一、实验目的通过一个简单的进程调度模拟程序的实现,加深对各种进程调度算法,进程切换的理解。
二、实验内容1、进程调度算法:采用动态最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)。
2、每个进程有一个进程控制块(PCB)表示。
进程控制块可以包含如下信息:●进程名----进程标示数ID;●优先数----Priority,优先数越大优先权越高;●到达时间----进程的到达时间为进程输入的时间;●进程还需要运行时间----AllTime,进程运行完毕AllTime =0;●已用CPU时间----CPUTime;●进程的阻塞时间StartBlock----表示当进程在运行StartBlock个时间片后,进程将进入阻塞状态;●进程的阻塞时间StartTime----表示当进程阻塞StartTime个时间片后,进程将进入就绪状态;●进程状态----State;●队列指针----Next,用来将PCB排成队列。
3、调度原则●进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。
进程的到达时间为进程输入的时间;●进程的运行时间以时间片为单位进行计算;●进程在就绪队列中带一个时间片,优先数加1;●每个进程的状态可以是就绪R(Ready)、运行R(Run)、阻塞B(Block)、或完成F(Finish)四种状态之一;●就绪进程获得CPU后都只能运行一个时间片,用已占用CPU时间加1来表示;●如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减3,然后把它插入就绪队列等待CPU;●每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查;●重复以上过程,直到所要进程都完成为止。
三、实验要求完成实验内容并写出实验报告,报告应具有以下内容:1、实验目的。
操作系统实验3进程的创建控制实验

操作系统实验3进程的创建控制实验实验三的目标是通过实现一个进程控制程序,来加深我们对进程创建和控制机制的理解,并通过实践来熟悉和掌握相关的编程技巧。
在进行实验之前,我们需要先了解进程的一些基本概念和相关知识。
首先,进程的创建是通过操作系统中的系统调用来完成的。
在Linux系统中,常用的创建进程的系统调用有fork(和exec(。
fork(系统调用可以创建一个新的进程,该进程与调用fork(的进程几乎完全相同;而exec(系统调用则在新创建的进程中执行一个新的程序。
另外,进程的控制机制主要是通过进程的状态来实现的。
进程可以处于就绪状态、运行状态和阻塞状态。
就绪状态的进程可以被调度器选择后立即运行,而阻塞状态的进程则需要等待一些条件满足后才能被唤醒并变为就绪状态。
实验三的具体内容包括:1. 编写一个程序,通过调用fork(创建多个子进程。
子进程和父进程可以并行执行,共享程序的代码和数据段。
2. 子进程通过调用exec(系统调用执行不同的程序。
可以通过调用不同的exec(函数或者传入不同的参数来执行不同的程序。
3. 子进程执行的程序可能会产生不同的结果,比如输出不同的字符串或者产生不同的返回值。
我们可以通过wait(系统调用等待子进程退出,并获取子进程的返回值。
4. 父进程可以通过调用waitpid(系统调用来选择等待一些特定的子进程,以及获取特定子进程的返回值。
通过实验三的实践,我将更加深入地了解进程的创建和控制机制。
实验三的实验结果将让我熟悉和掌握相关的编程技巧,为我今后更加熟练地编写和控制进程打下坚实的基础。
总之,实验三是一个非常有意义的实验,将帮助我更加深入地理解进程的创建和控制机制,并通过实践获得相关的编程技巧。
这将对我今后的学习和实践有很大的帮助。
计算机操作系统实验二

计算机操作系统实验二一、实验目的本实验旨在通过实际操作,深入理解和掌握计算机操作系统中的进程与线程管理。
通过实验,我们将了解进程的创建、执行、阻塞、唤醒等状态以及线程的创建、同步、通信等操作。
同时,通过实验,我们将学习如何利用进程和线程提高程序的并发性和效率。
二、实验内容1、进程管理a.进程的创建与执行:通过编程语言(如C/C++)编写一个程序,创建一个新的进程并执行。
观察和记录进程的创建、执行过程。
b.进程的阻塞与唤醒:编写一个程序,使一个进程在执行过程中发生阻塞,并观察和记录阻塞状态。
然后,通过其他进程唤醒该进程,并观察和记录唤醒过程。
c.进程的状态转换:根据实际操作,理解和分析进程的状态转换(就绪状态、阻塞状态、执行状态)以及转换的条件和过程。
2、线程管理a.线程的创建与同步:编写一个多线程程序,创建多个线程并观察和记录线程的创建过程。
同时,使用同步机制(如互斥锁或信号量)实现线程间的同步操作。
b.线程的通信:通过消息队列或其他通信机制,实现多个线程间的通信。
观察和记录线程间的通信过程以及通信对程序执行的影响。
c.线程的状态转换:根据实际操作,理解和分析线程的状态转换(新建状态、就绪状态、阻塞状态、终止状态)以及转换的条件和过程。
三、实验步骤1、按照实验内容的要求,编写相应的程序代码。
2、编译并运行程序,观察程序的执行过程。
3、根据程序的输出和实际操作情况,分析和理解进程与线程的状态转换以及进程与线程管理的相关原理。
4、修改程序代码,尝试不同的操作方式,观察程序执行结果的变化,进一步深入理解和掌握进程与线程管理。
5、完成实验报告,总结实验过程和结果,提出问题和建议。
四、实验总结通过本次实验,我们深入了解了计算机操作系统中的进程与线程管理原理和实践操作。
在实验过程中,我们不仅学习了如何利用编程语言实现进程和线程的操作,还通过实际操作观察和分析了进程与线程的状态转换以及进程与线程管理的基本原理。
进程控制实验报告

进程控制实验报告进程控制实验报告引言:进程控制是操作系统中的重要概念之一,它负责管理和调度计算机系统中的各个进程,确保它们能够按照一定的顺序和优先级进行执行。
本实验旨在通过编写一个简单的进程控制程序,加深对进程控制的理解,并探索其在实际应用中的作用。
实验目的:1. 理解进程控制的基本概念和原理;2. 掌握进程创建、终止和切换的方法;3. 熟悉进程调度算法的实现;4. 分析进程控制在实际应用中的意义和效果。
实验过程:本次实验中,我们选择使用C语言编写一个简单的进程控制程序,通过创建多个进程并进行调度,观察它们的执行顺序和状态变化。
首先,我们定义了一个进程结构体,包含进程ID、进程状态和进程优先级等信息。
然后,我们编写了创建进程的函数,通过调用系统调用接口fork()来创建新的进程,并为其分配唯一的进程ID。
在进程创建完成后,我们实现了一个简单的进程调度算法,根据进程的优先级和状态来决定下一个要执行的进程。
我们使用了优先级队列来管理进程,将优先级高的进程排在队列的前面,以确保它们能够优先执行。
接下来,我们模拟了进程的运行过程,通过设置进程的状态和优先级,来模拟进程的创建、终止和切换。
我们观察到,当一个进程被创建时,它会被添加到就绪队列中,等待系统调度执行。
当一个进程的时间片用完或者发生阻塞时,它会被暂停并切换到下一个就绪进程执行。
实验结果:通过多次运行实验程序,我们观察到进程的创建、终止和切换过程。
我们发现,进程的创建是一个相对较慢的过程,而进程的切换则非常迅速。
这是因为进程的创建需要为其分配资源和初始化环境,而进程的切换只需要保存和恢复进程的状态即可。
我们还发现,进程的优先级对于进程的执行顺序有重要影响。
当一个进程的优先级较高时,它会被优先执行,而其他进程则需要等待。
这使得系统能够根据进程的重要性和紧急程度来进行合理的调度,提高系统的效率和响应速度。
讨论与总结:进程控制是操作系统中非常重要的一部分,它负责管理和调度计算机系统中的各个进程。
山东大学操作系统实验一

软件学院操作系统实验报告实验题目:实验一、进程控制实验学号:日期:2013年04月12日班级:5班姓名:韩俊晓Email:实验目的:加深对于进程并发执行概念的理解。
实践并发进程的创建和控制方法。
观察和体验进程的动态特性。
进一步理解进程生命期期间创建、变换、撤销状态变换的过程。
掌握进程控制的方法,了解父子进程间的控制和协作关系。
练习Linux系统中进程创建与控制有关的系统调用的编程和调试技术。
实验要求:编写一个多进程并发执行程序。
父进程首先创建一个执行ls命令的子进程然后再创建一个执行ps命令的子进程,并控制ps命令总在ls 命令之前执行。
硬件环境:实验室计算机软件环境:Ubuntu08.4-Linux操作系统gcc version 4.1.2gedit 2.18.2OpenOffice 2.3实验步骤:1.实验说明:1)与进程创建、执行有关的系统调用说明进程可以通过系统调用fork()创建子进程并和其子进程并发执行.子进程初始的执行映像是父进程的一个复本.子进程可以通过exec()系统调用族装入一个新的执行程序。
父进程可以使用wait()或waitpid()系统调用等待子进程的结束并负责收集和清理子进程的退出状态。
fork()系统调用语法:#include <unistd.h>pid_t fork(void);fork成功创建子进程后将返回子进程的进程号,不成功会返回-1. exec 系统调用有一组6个函数,其中示例实验中引用了execve 系统调用语法:#include <unistd.h>int execve(const char *path, const char *argv[], const char * envp[]); path 要装入的新的执行文件的绝对路径名字符串.argv[] 要传递给新执行程序的完整的命令参数列表(可以为空). envp[] 要传递给新执行程序的完整的环境变量参数列表(可以为空). Exec执行成功后将用一个新的程序代替原进程,但进程号不变,它绝不会再返回到调用进程了。
操作系统实验报告实验一进程管理

实验一进程管理一、目的进程调度是处理机管理的核心内容。
本实验要求编写和调试一个简单的进程调度程序。
通过本实验加深理解有关进程控制块、进程队列的概念,并体会和了解进程调度算法的具体实施办法。
二、实验内容及要求1、设计进程控制块PCB的结构(PCB结构通常包括以下信息:进程名(进程ID)、进程优先数、轮转时间片、进程所占用的CPU时间、进程的状态、当前队列指针等。
可根据实验的不同,PCB结构的内容可以作适当的增删)。
为了便于处理,程序中的某进程运行时间以时间片为单位计算。
各进程的轮转时间数以及进程需运行的时间片数的初始值均由用户给定。
2、系统资源(r1…r w),共有w类,每类数目为r1…r w。
随机产生n进程P i(id,s(j,k),t),0<=i<=n,0<=j<=m,0<=k<=dt为总运行时间,在运行过程中,会随机申请新的资源。
3、每个进程可有三个状态(即就绪状态W、运行状态R、等待或阻塞状态B),并假设初始状态为就绪状态。
建立进程就绪队列。
4、编制进程调度算法:时间片轮转调度算法本程序用该算法对n个进程进行调度,进程每执行一次,CPU时间片数加1,进程还需要的时间片数减1。
在调度算法中,采用固定时间片(即:每执行一次进程,该进程的执行时间片数为已执行了1个单位),这时,CPU时间片数加1,进程还需要的时间片数减1,并排列到就绪队列的尾上。
三、实验环境操作系统环境:Windows系统。
编程语言:C#。
四、实验思路和设计1、程序流程图2、主要程序代码//PCB结构体struct pcb{public int id; //进程IDpublic int ra; //所需资源A的数量public int rb; //所需资源B的数量public int rc; //所需资源C的数量public int ntime; //所需的时间片个数public int rtime; //已经运行的时间片个数public char state; //进程状态,W(等待)、R(运行)、B(阻塞)//public int next;}ArrayList hready = new ArrayList();ArrayList hblock = new ArrayList();Random random = new Random();//ArrayList p = new ArrayList();int m, n, r, a,a1, b,b1, c,c1, h = 0, i = 1, time1Inteval;//m为要模拟的进程个数,n为初始化进程个数//r为可随机产生的进程数(r=m-n)//a,b,c分别为A,B,C三类资源的总量//i为进城计数,i=1…n//h为运行的时间片次数,time1Inteval为时间片大小(毫秒)//对进程进行初始化,建立就绪数组、阻塞数组。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一、进程控制实验1.1 实验目的加深对于进程并发执行概念的理解。
实践并发进程的创建和控制方法。
观察和体验进程的动态特性。
进一步理解进程生命期期间创建、变换、撤销状态变换的过程。
掌握进程控制的方法,了解父子进程间的控制和协作关系。
练习Linux 系统中进程创建与控制有关的系统调用的编程和调试技术。
1.2 实验说明1)与进程创建、执行有关的系统调用说明进程可以通过系统调用fork()创建子进程并和其子进程并发执行.子进程初始的执行映像是父进程的一个复本.子进程可以通过exec()系统调用族装入一个新的执行程序。
父进程可以使用wait()或waitpid()系统调用等待子进程的结束并负责收集和清理子进程的退出状态。
fork()系统调用语法:#include <unistd.h> pid_tfork(void);fork 成功创建子进程后将返回子进程的进程号,不成功会返回-1.exec 系统调用有一组6 个函数,其中示例实验中引用了execve 系统调用语法:#include <unistd.h>int execve(const char *path, const char *argv[], const char * envp[]); path 要装入的新的执行文件的绝对路径名字符串.argv[] 要传递给新执行程序的完整的命令参数列表(可以为空).envp[] 要传递给新执行程序的完整的环境变量参数列表(可以为空).Exec 执行成功后将用一个新的程序代替原进程,但进程号不变,它绝不会再返回到调用进程了。
如果exec 调用失败,它会返回-1。
wait() 系统调用语法:#include <sys/types.h>#include <sys/wait.h> pid_twait(int *status);pid_t waitpid(pid_t pid,int *status,int option); status 用于保留子进程的退出状态pid 可以为以下可能值:-1 等待所有PGID 等于PID 的绝对值的子进程1 等待所有子进程0 等待所有PGID 等于调用进程的子进程>0 等待PID 等于pid 的子进程option 规定了调用waitpid 进程的行为:WNOHANG 没有子进程时立即返回WUNTRACED 没有报告状态的进程时返回wait 和waitpid 执行成功将返回终止的子进程的进程号,不成功返回-1。
getpid()系统调用语法:#include <sys/types.h>#include <unistd.h> pid_tgetpid(void);pid_t getppid(void);getpid 返回当前进程的进程号,getppid 返回当前进程父进程的进程号2)与进程控制有关的系统调用说明可以通过信号向一个进程发送消息以控制进程的行为。
信号是由中断或异常事件引发的,如:键盘中断、定时器中断、非法内存引用等。
信号的名字都以SIG 开头,例如SIGTERM、SIGHUP。
可以使用kill -l 命令查看系统当前的信号集合。
信号可在任何时间发生,接收信号的进程可以对接收到的信号采取3种处理措施之一:•忽略这个信号•执行系统默认的处理•捕捉这个信号做自定义的处理信号从产生到被处理所经过的过程:产生(generate)-> 挂起(pending)-> 派送(deliver)-> 部署(disposition) 或忽略(igore)一个信号集合是一个C 语言的sigset_t 数据类型的对象,sigset_t 数据类型定义在<signal.h>中。
被一个进程忽略的所有信号的集合称为一个信号掩码(mask)。
从程序中向一个进程发送信号有两种方法:调用shell 的kill 命令,调用kill系统调用函数。
kill能够发送除杀死一个进程(SIGKILL、SIGTERM、SIGQUIT)之外的其他信号,例如键盘中断(Ctrl+C)信号SIGINT,进程暂停(Ctrl+Z)信号SIGTSTP 等等。
调用Pause 函数会令调用进程的执行挂起直到一个任意信号到来后再继续运行。
调用sleep 函数会令调用进程的执行挂起睡眠指定的秒数或一个它可以响应的信号到来后继续执行。
每个进程都能使用signal 函数定义自己的信号处理函数,捕捉并自行处理接收的除SIGSTOP 和SIGKILL 之外的信号。
以下是有关的系统调用的语法说明。
kill 系统调用语法:#include <sys/types.h>#include <signal.h>int kill(pid_t pid, int sig);pid 接收信号的进程号signal 要发送的信号kill 发送成功返回接收者的进程号,失败返回-1。
pause 系统调用语法:#include <unistd.h> intpause(void);pause 挂起调用它的进程直到有任何信号到达。
调用进程不自定义处理方法,则进行信号的默认处理。
只有进程自定义了信号处理方法捕获并处理了一个信号后,pause 才会返回调进程。
pause 总是返回-1,并设置系统变量errno 为EINTR。
sleep 系统调用语法:#include <unistd.h>unsigned int sleep(unsigned int seconds);seconds 指定进程睡眠的秒数如果指定的秒数到,sleep 返回0。
signal 系统调用语法为:#include <signal.h> typedef void(*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);signum 要捕捉的信号handler 进程中自定义的信号处理函数名signal 调用成功会返回信号处理函数的返回值,不成功返回-1,并设置系统变量errno 为SIG_ERR。
1.3 示例实验以下实验示例程序应实现一个类似子shell 子命令的功能,它可以从执行程序中启动另一个新的子进程并执行一个新的命令和其并发执行.1)打开一终端命令行窗体,新建一个文件夹,在该文件夹中建立以下名为pctl.c 的C语言程序:/**Filename : pctl.c*copyright : (C) 2006 by zhanghonglie*Function : 父子进程的并发执行*/#include "pctl.h"int main(int argc, char *argv[]){ int i;int pid; //存放子进程号int status; //存放子进程返回状态char *args[] ={"/bin/ls","-a",NULL}; //子进程要缺省执行的命令signal(SIGINT,(sighandler_t)sigcat);//注册一个本进程处理键盘中断的函数pid=fork() ; //建立子进程if(pid<0) // 建立子进程失败?{printf("Create Process fail!\n"); exit(EXIT_FAILURE);}if(pid == 0) // 子进程执行代码段{//报告父子进程进程号printf("I am Child process %d\nMy father is %d\n",getpid(),getppid());pause(); //暂停,等待键盘中断信号唤醒//子进程被键盘中断信号唤醒继续执行printf("%d child will Running: \n",getpid()); // if(argv[1] !=NULL){//如果在命令行上输入了子进程要执行的命令//则执行输入的命令for(i=1; argv[i] != NULL; i++) printf("%s ",argv[i]);printf("\n");//装入并执行新的程序status = execve(argv[1],&argv[1],NULL);} else{//如果在命令行上没输入子进程要执行的命令//则执行缺省的命令for(i=0; args[i] != NULL; i++) printf("%s ",args[i]); printf("\n");//装入并执行新的程序status = execve(args[0],args,NULL);}}else //父进程执行代码段{printf("\nI am Parent process %d\n",getpid()); //报告父进程进程号if(argv[1] != NULL){ //如果在命令行上输入了子进程要执行的命令//则父进程等待子进程执行结束printf("%d Waiting for child done.\n\n",pid); waitpid(pid,&status,0); //等待子进程结束printf("\nMy child exit! status = %d\n\n",status);} else{//如果在命令行上没输入子进程要执行的命令//唤醒子进程,与子进程并发执行不等待子进程执行结束,if(kill(pid,SIGINT) >= 0)printf("%d Wakeup %d child.\n",getpid(),pid) ; printf("%d don't Wait for child done.\n\n",getpid());} }return EXIT_SUCCESS;}2)再建立以下名为pctl.h 的C 语言头文件:#include <sys/types.h>#include <wait.h>#include <unistd.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>//进程自定义的键盘中断信号处理函数typedef void (*sighandler_t) (int); void sigcat(){printf("%d Process continue\n",getpid());}3)建立以下项目管理文件Makefilehead = pctl.h srcs = pctl.c objs = pctl.o opts= -g -call: pctlpctl: $(objs) gcc $(objs) -o pctl pctl.o:$(srcs) $(head) gcc $(opts) $(srcs) clean:rm pctl *.o4)输入make 命令编译连接生成可执行的pctl 程序$g makegcc -g -c pctl.cgcc pctl.o -o pctl5)执行pctl 程序(注意进程号是动态产生的,每次执行都不相同)$ ./pctlI am Child process 4113My father is 4112I am Parent process 4112 Wakeup 4113 child.4112don't Wait for child done.4113Process continue4113 child will Running: /bin/ls -a. .. Makefile pctl pctl.c pctl.h pctl.o$以上程序的输出说明父进程4112 创建了一个子进程4113,子进程执行被暂停。