进程创建之fork系统调用

进程创建之fork系统调用
进程创建之fork系统调用

4 进程创建 (1)

4.1 实验内容及要求 (1)

4.2 实验目的 (1)

4.3 实验环境 (1)

4.4 实验思路 (1)

4.5 实验代码 (2)

4.6 运行结果 (3)

4.7 实验心得 (3)

4 进程创建

4.1 实验内容及要求

利用fork()系统调用创建进程。要求如下:

编制一段程序,使用系统调用fork( )创建两个子进程,这样在此程序运行时,在系统中就有一个父进程和两个子进程在活动。每一个进程在屏幕上显示一个字符,其中父进程显示字符A,子进程分别显示字符 B和字符C。试观察、记录并分析屏幕上进程调度的情况。

4.2 实验目的

了解进程的创建过程,进一步理解进程的概念,明确进程和程序的区别。

4.3 实验环境

Ubuntu 18.04.1 LTS 64位,编译器gcc 7.3.0 (Ubuntu 7.3.0-16ubuntu3)

4.4 实验思路

(1)可用fork()系统调用来创建一个新进程。

系统调用格式:pid=fork()

fork()返回值意义如下:

=0:若返回值为0,表示当前进程是子进程。

>0:若返回值大于0,表示当前进程是父进程,返回值为子进程的pid值。

<0:若返回值小于0,表示进程创建失败。

如果fork()调用成功,它向父进程返回子进程的pid,并向子进程返回0,即fork()被调用了一次,但返回了两次。此时OS在内存中建立一个新进程,所建的新进程是调用fork()父进程的副本,称为子进程。子进程继承了父进程的许多特性,并具有与父进程完全相同的用户级上下文。父进程与子进程并发执行。

(2)编译和执行的方法:

编译:在shell提示符下输入gcc 源文件名 -o 可执行文件名

运行:在shell提示符下输入 ./可执行文件名

4.5 实验代码

#include

#include

#include

int main(void) {

pid_t p1=fork();pid_t p2=fork(); //迭代调用fork(),创建三个新进程printf("this is parent, pid = %d\n", getpid()); //父进程

if(p1<0||p2<0){ //fork()失败

printf("fork failed with p1=%d, p2=%d\n", p1, p2);

exit(1);

}if(p1==0&&p2==0){ //子进程B创建的子进程D,即孙进程

printf("D in grandson Damson, pid = %d\n", getpid());

}if(p1==0&&p2>0){ //父进程创建的子进程B

printf("B in child Blueberry, pid = %d\n", getpid());

}if(p1>0&&p2==0){ //父进程创建的子进程C

printf("C in child Carambola, pid = %d\n", getpid());

}if(p1>0&&p2>0){ //父进程

printf("A in parent Apple, pid = %d\n", getpid());

}return 0;

}

4.6 运行结果

编译源文件4.c得到可执行文件文件4,运行如下:

4.7 实验心得

每次调用fork()函数,从代码层理解,相当于自fork()之后的所有代码复制了一份给新进程。原来的进程和新进程执行相同的代码,但进程标识PID不同。

fork函数和子进程

Fork函数 函数pid_t fork(void) 正确返回:在父进程中返回子进程的进程号,在子进程中返回0 错误返回:-1 子进程是父进程的一个拷贝。即,子进程从父进程得到了数据段和堆栈段的拷贝,这些需要分配新的内存;而对于只读的代码段,通常使用共享内存的方式访问。fork返回后,子进程和父进程都从调用fork函数的下一条语句开始执行。父进程与子进程的不同之处在于:fork的返回值不同——父进程中的返回值为子进程的进程号,而子进程为0。 以下是fork的两个示例程序: //fork.c #include #include void main () { int pid; //printf("Process [%d] begin",getpid()); //print twice printf("Process [%d] begin\n",getpid()); //print once //由于fork时pc等值的拷贝,子进程只会从fork处开始执行 pid = fork(); if (pid < 0) printf("error in fork!"); else if (pid == 0) printf("I'm child process, my pid is %d\n", getpid()); else printf("I'm parent process, my pid is %d\n", getpid()); printf("Process [%d] end\n",getpid()); return; } 输出结果: 使用printf("Process [%d] begin\n",getpid())时 Process [11155] begin I'm parent process, my pid is 11155

操作系统实验-进程控制

实验一、进程控制实验 1.1 实验目的 加深对于进程并发执行概念的理解。实践并发进程的创建和控制方法。观察和体验进程的动态特性。进一步理解进程生命期期间创建、变换、撤销状态变换的过程。掌握进程控制的方法,了解父子进程间的控制和协作关系。练习Linux 系统中进程创建与控制有关的系统调用的编程和调试技术。 1.2 实验说明 1)与进程创建、执行有关的系统调用说明进程可以通过系统调用fork()创建子进程并和其子进程并发执行.子进程初始的执行映像是父进程的一个复本.子进程可以通过exec()系统调用族装入一个新的执行程序。父进程可以使用wait()或waitpid()系统调用等待子进程的结束并负责收集和清理子进程的退出状态。 fork()系统调用语法: #include pid_t fork(void); fork 成功创建子进程后将返回子进程的进程号,不成功会返回-1. exec 系统调用有一组6 个函数,其中示例实验中引用了execve 系统调用语法: #include int execve(const char *path, const char *argv[], const char * envp[]); path 要装入 的新的执行文件的绝对路径名字符串. argv[] 要传递给新执行程序的完整的命令参数列表(可以为空). envp[] 要传递给新执行程序的完整的环境变量参数列表(可以为空).

Exec 执行成功后将用一个新的程序代替原进程,但进程号不变,它绝不会再返回到调用进程了。如果exec 调用失败,它会返回-1。 wait() 系统调用语法: #include #include pid_t wait(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 #include pid_t getpid(void); pid_t getppid(void); getpid 返回当前进程的进程号,getppid 返回当前进程父进程的进程号 2)与进程控制有关的系统调用说明可以通过信号向一个进程发送消息以控制进程的 行为。信号是由中断或异常事件引发的,如:键盘中断、定时器中断、非法内存引

惠州学院操作系统进程的创建与并发执行实验(精编文档).doc

【最新整理,下载后即可编辑】 实验一进程的创建与并发执行 一、实验目的: (1) 熟悉Linux工作环境、文本编辑器工具和GCC工具 (2) 加深对进程概念的理解,明确进程和程序的区别 (3) 进一步认识并发进程的实质和特征 二、实验仪器及材料: 微型计算机、Linux系统 三、实验内容: 1、任务1:进程创建 编写一段程序,让父进程产生两个子进程,父进程显示字符“a”、两个子进程,分别显示字符“b”、“c”。 任务2:将上述的输出字符改为输出较长的字符串,观察进程并发执行,分析执行结果。 2、源代码: 任务1: #include main(){ int p1, p2; while ((p1=fork())==-1); /*父进程创建第一个进程,直到成功*/ if (p1==0) /*0返回给子进程1*/ printf(“b\n”); /*P1的处理过程*/ else/*正数返回给父进程(子进程号)*/ { while ((p2=fork())==-1); /*父进程创建第二个进程,直到成功*/ if (p2==0) /* 0返回给子进程2*/ printf(“c\n”); /*P2的处理过程*/ else printf(“a\n”); /*P2创建完成后,父进程的处理过程*/

} } 任务2: #include main(){ int p1, p2; while ((p1=fork())==-1); /*父进程创建第一个进程,直到成功*/ if(p1==0) while (1) printf(“A ”) else { while ((p2=fork())==-1); /*父进程创建第二个进程,直到成功*/ if (p2==0) while (1) printf(“B ”) else /*P2创建完成后,父进程的处理过程*/ while (1) printf(“P ”); } } 四、实验结果记录: 任务1:

第二章进程管理答案

第二章进程管理 一、单项选择题 1、顺序程序和并发程序的执行相比,()。 A.基本相同 B. 有点不同 C.并发程序执行总体上执行时间快 D.顺序程序执行总体上执行时间快 2、在单一处理机上,将执行时间有重叠的几个程序称为()。 A.顺序程序 B. 多道程序 C.并发程序 D. 并行程序 3、进程和程序的本质区别是()。 A.存储在内存和外存 B.顺序和非顺序执行机器指令 C.分时使用和独占使用计算机资源 D.动态和静态特征 4、在下列特性中,不是进程的特性的是()。 A. 异步性 B. 并发性 C. 静态性 D. 动态性 5 A 6 A. 7 A. 8 A. 9 A. 10 A. 11 A. 12。 A. 13 A. 14 A. 15 A. 16、在操作系统中,对信号量S的P原语操作定义中,使进程进入相应阻塞队列等待的条件是()。 A. S>0 B. S=0 C. S<0 D. S≠0 17、信号量S的初值为8,在S上执行了10次P操作,6次V操作后,S的值为()。 A.10 B.8 C.6 D.4 18、在进程通信中,使用信箱方式交换信息的是()。 A.低级通信B.高级通信C.共享存储器通信D.管道通信 19.( )必定会引起进程切换。A.一个进程被创建后进入就绪态B.一个进程从运行态变成等待态c.一个进程从运行态变成就绪态 D.一个进程从等待态变成就绪态 20、操作系统使用( )机制使计算机系统能实现进程并发执行,保证系统正常工作。 A.中断B.查询c.同步D互斥 21.对于一个单处理器系统来说,允许若干进程同时执行,轮流占用处理器.称它们为()的。 A.顺序执行 B.同时执行c.并行执行D.并发执行

操作系统实验报告--进程的创建

操作系统原理实验报告(一) 进程的创建 2016年11月27日星期日

实验内容: 进程的创建 编写一段源程序,使系统调用fork()创建两个子进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。试观察纪录屏幕上的显示结果,并分析原因。 源代码: #include #include #include int main(){ printf("\n梦想起航的地方:\n"); pid_t fpid1,fpid2;/*fpid表示fork()函数的返回值*/ printf("得到父进程的ID:%d\n",getpid()); printf("\n开始调用fork函数:\n如果调用成功应该会生成一个子进程1\n返回值:若成功调用一次则返回两个值,\n子进程返回0,父进程返回子进程标记(ID);\n 否则,出错返回-1。\n"); fpid1=fork(); fpid2=fork(); if(fpid1<0)exit(0); else if(fpid1>0) printf("\n这个是父进程打印:a\n"); else if(fpid1==0) printf("\n这个是子进程1的打印:b\n"); if(fpid2<0)exit(0); else if(fpid2>0) printf("\n这个还是父进程'打印:a\n"); else if(fpid2==0); printf("\n这个是子进程2的打印:c\n"); }

第二章-操作系统进程(练习题答案)

第二章进程管理 1.操作系统主要是对计算机系统全部 (1) 进行管理,以方便用户、提高计算机使 用效率的一种系统软件。它的主要功能有:处理机管理、存储管理、文件管理、 (2) 管 理和设备管理等。Windows和Unix是最常用的两类操作系统。前者是一个具有图形界面的 窗口式的 (3) 系统软件,后者是一个基本上采用 (4) 语言编制而成的 的系统软件。在 (5) 操作系统控制下,计算机能及时处理由过程控制反馈的信息 并作出响应。 供选答案: (1): A. 应用软件 B. 系统软硬件 C. 资源 D. 设备 (2): A. 数据 B. 作业 C. 中断 D. I/O (3): A. 分时 B. 多任务 C. 多用户 D. 实时 (4): A. PASCAL B. 宏 C. 汇编 D. C (5): A. 网络 B. 分时 C. 批处理 D. 实时 答案:CBBDD 2.操作系统是对计算机资源进行的 (1) 系统软件,是 (2) 的接口。 在处理机管理中,进程是一个重要的概念,它由程序块、 (3) 和数据块三部 分组成,它有3种基本状态,不可能发生的状态转换是 (4) 。 虚拟存储器的作用是允许程序直接访问比内存更大的地址空间,它通常使用 (5) 作为它的一个主要组成部分。 供选答案: (1): A. 输入和输出 B. 键盘操作 C. 管理和控制 D. 汇编和执行 (2): A. 软件和硬件 B. 主机和外设 C. 高级语言和机器语言 D. 用户和计算机 (3): A. 进程控制块 B. 作业控制块 C. 文件控制块 D. 设备控制块 (4): A. 运行态转换为就绪态 B. 就绪态转换为运行态 C. 运行态转换为等待态 D. 等待态转换为运行态 (5): A. 软盘 B. 硬盘 C. CDROM D. 寄存器 答案:CDADB 3.在计算机系统中,允许多个程序同时进入内存并运行,这种方法称为 D。 A. Spodling技术 B. 虚拟存储技术 C. 缓冲技术 D. 多道程序设计技术 4.分时系统追求的目标是 C。 A. 高吞吐率 B. 充分利用内存 C. 快速响应 D. 减少系统开销 5.引入多道程序的目的是 D。

进程的创建与并发执行-带答案版课案

实验二进程管理 2.1 进程的创建与并发执行 1.实验目的 (1) 加深对进程概念的理解,理解进程和程序的区别。 (2) 认识并发进程的实质。分析进程争用资源的现象,学习解决进程互斥的方法。 (3) 理解系统调用和用户命令的区别。 2.实验类型:验证型 3.实验学时:2 4.实验原理和知识点 (1) 实验原理:程序的并发执行具有随机性和不可再现性。程序并发执行会导致资源共享和资源竞争,各程序向前执行的速度会受资源共享的制约。程序的动态执行过程用进程这个概念来描述。由于向前推进的速度不可预知,所以多个进程并发地重复执行,整体上得到的结果可能不同。但要注意,就其中某单个进程而言,其多次运行结果是确定的。 (2) 知识点:进程、子进程、并发执行的特性; 5.实验环境(硬件环境、软件环境): (1)硬件环境:Intel Pentium III 以上CPU,128MB以上内存,2GB以上硬盘 (2)软件环境:linux操作系统。 6. 预备知识 (1) fork()系统调用 头文件:#include unix standard header /*是POSIX标准定义的unix类系统定义符号常量的头文件,包含了许多UNIX系统服务的函数原型,例如read函数、write函数和getpid函数*/ 函数原型: pid_t fork(void); /*是Linux下的进程号类型,也就是Process ID _ Type 的缩写。其实是宏定义的unsigned int类型*/ 函数功能:fork的功能是创建子进程。调用fork的进程称为父进程。如图2.1所示。子进程是父进程的一个拷贝,它继承了父进程的用户代码、组代码、环境变量、已打开的文件代码、工作目录及资源限制。fork语句执行后,内核向父进程返回子进程的进程号,向子进程返回0。父子进程都从fork()的下一句开始并发执行。 返回值: 返回值==-1:创建失败。 返回值==0:程序在子进程中。 返回值>0:程序在父进程中。(该返回值是子进程的进程号) 编程提示:虽然子进程是父进程的一个复制品,但父子的行为是不同的。编程时要抓住内核的返回值。通过返回值,可以知道是父进程还是子进程,因而可以编写不同行为的代码。

fork函数实验总结

针对fork函数难以理解,根据网上的解释,参考他人代码,做了如下实验,并附以实验分析 2 #include 3 #include 4 #include 5 #include 6 #include 7 8 int main () 9 { 10 pid_t pc,pr; 11 pc=fork(); (gdb) 12 13 if (pc<0) 14 { 15 printf("error fork.\n"); 16 17 } 18 else if (pc==0) 19 { 20 printf("this is pc=%d\n",getpid()); 21 sleep(5); (gdb) 22 printf("5 s over\n"); 23 //exit(0); 24 } 25 pr=fork(); 26 if (pr==0) 27 { 28 printf("this is pr =%d\n",getpid()); 29 } 30 31 else if (pr>0&&pc>0) (gdb) 32 printf("this is main =%d",getpid()); 33 34 35 36 37 38 } (gdb) b 12

Breakpoint 1 at 0x804849d: file /home/lsp/fork3.c, line 12. (gdb) b 19 Breakpoint 2 at 0x80484b7: file /home/lsp/fork3.c, line 19. (gdb) b 24 Breakpoint 3 at 0x80484e4: file /home/lsp/fork3.c, line 24. (gdb) b 26 Breakpoint 4 at 0x80484ec: file /home/lsp/fork3.c, line 26. (gdb) run Starting program: /home/lsp/fork3 Detaching after fork from child process 13200. ---说明pc=fork()函数已经建立子进程 this is pc=13200 Breakpoint 1, main () at /home/lsp/fork3.c:13 13 if (pc<0) (gdb) 5 s over this is pr =13201 --说明pc=fork()进程13200启动了新的子进程pr 其pid=13201 next Breakpoint 3, main () at /home/lsp/fork3.c:25 25 pr=fork(); --父进程停在pr=fork()处, (gdb) next Detaching after fork from child process 13254. this is pr =13254 --此处pr的pid=13254 与上一个pr=13201不同,这说明此处的pr是由main创建的 Breakpoint 4, main () at /home/lsp/fork3.c:26 26 if (pr==0) (gdb) next 31 else if (pr>0&&pc>0) (gdb) next 32 printf("this is main =%d",getpid()); (gdb) next 38 } (gdb) next 0x00a6d5d6 in __libc_start_main () from /lib/libc.so.6 (gdb) next Single stepping until exit from function __libc_start_main, which has no line number information. this is main =13199 ---main函数退出,器pid=13199 Program exited with code 023. (gdb)

(完整版)操作系统第二章作业答案

第二章作业 1.操作系统中为什么要引入进程的概念?为了实现并发进程中的合作和协调,以及保证系统的安全,操作系统在进程管理方面要做哪些工作? 答:为了从变化角度动态地分析研究可以并发执行的程序,真实的反应系统的独立性、并发性、动态性和相互制约,操作系统中不得不引入进程的概念。 为了防止操作系统及其关键的数据结构如:PCB等,受到用户程序破坏,将处理机分为核心态和用户态。对进程进行创建、撤销以及在某些进程状态之间的转换控制。 2.试描述当前正在运行的进程状态改变时,操作系统进行进程切换的步骤。答:分为两种情况: (1):运行状态就绪状态:根据进程的自身的情况插入到就绪队列的适当位置,系统收回处理及转入进程调度程序重新进行调度。 (2):运行状态→阻塞状态:系统会调用进程调度程序重新选择一个进程投入运行。 3.现代操作系统一般都提供多任务的环境,是回答以下问题。 为支持多进程的并发执行,系统必须建立哪些关于进程的数据结构? 答:系统必须建立PCB。 为支持进程的状态变迁,系统至少应该供哪些进程控制原语? 答:阻塞、唤醒、挂起和激活原语。 当进程的状态变迁时,相应的数据结构发生变化吗? 答:会根据状态的变迁发生相应的变化。例如:将进程PCB中进程的状态从阻塞状态改为就绪状态,并将进程从阻塞队列摘下,投入到就绪队列中。 4.什么是进程控制块?从进程管理、中断处理、进程通信、文件管理、设备管理及存储管理的角度设计进程控制块应该包含的内容。 答:PCB:描述进程本身的特征、状态、调度信息以及对资源占有情况等的数据结构,是进程存在的唯一标识。 进程控制块所包含的内容: ①进程信息描述;②CPU信息状态;③进程调度信息;④进程控制和资源占用信息。 5.假设系统就绪队列中有10个进程,这10个进程轮换执行,每隔300ms轮换一次,CPU在进程切换时所花费的时间是10ms,试问系统化在进程切换上的开销占系统整个时间的比例是多少? 解:P=(10*10)/[(300+10)*10]=3.2% 6.试述线程的特点及其与进程之间的关系。 答:线程的特点:是被独立分派和调度的基本单位。线程与进程的关系:线程是进程的一部分,是进程内的一个实体;一个进程可以有多个线程,但至少必须有一个线程。

操作系统课程设计并发进程的模拟

课程设计说明书题目: 并发进程的模拟 院系:计算机科学与工程 专业班级: 学号: 学生姓名: 指导教师: 2014年 11月 12 日

安徽理工大学课程设计(论文)任务书 2014年11月21日

安徽理工大学课程设计(论文)成绩评定表 I

目录 1问题描述 0 2需求分析 0 3概要设计 (1) 1. P操作 (1) 2. V操作 (2) 3. P,V操作实现进程同步 (3) 4. 功能模块设计 (4) 4详细设计 (6) 1.主界面的设计程序 (6) 2.进程Pa的执行 (7) 3.进程Pb的执行 (8) 4.进程Pc的执行 (8) 5.按钮的执行 (9) 5 调试的分析与运行结果 (10) 6 设计体会 (12) 参考文献 (13)

1问题描述 在进程并发执行的过程中,进程之间存在协作的关系,例如,有互斥、同步的关系。该课程设计的是了解进程同步的概念,理解信号量机制的原理,掌握运用信号量解决进程并发控制问题的方法,进而学会运用进程的同步,利用信号灯的P,V操作实现三个进程的同步。这三个进程的同步关系如下: 从上图中可以看出:任务启动后pa先执行,当它结束后,pb、pc可以开始执行,pb、pc 都执行完毕后,任务终止;设两个同步信号灯sb、sc分别表示进程pb和pc能否开始执行,其初值均为0。 在现代操作系统中,有大量的并发进程在活动,它们都处在不断的申请资源,使用资源以及其它进程的相互制约的活动中,这些进程什么时候停止运行,什么时候该继续向前推进,应根据事先的约定来规范它们的行为,这时我们可以根据同步信号灯来实现进程的同步协调工作。例如本题中,只有pa进程顺利的进行完,Pb,Pc这两个进程才能正常的进行。如果进程Pa在进行中出现停止或中断,则Pb和Pc是不会顺利的完成的;而进程Pb,Pc这两个进程是并行执行的,两个进程的进行是互不干扰的,只要进程Pa完成后,进程Pb和Pc才会正常执行,否则只有处在等待就绪中。 2需求分析 进程执行的并发性的意义是关于一组进程的执行在是时间上是重叠的,从宏观上看,并发性反应的是一个时间段中几个进程都在同一个处理器上,处于运行还未运行结束状态。从微观上看,任何一个时刻仅有一个进程在处理器上运行。并发的实质是一个处理器在几个进程之间的多路复用,并发是对有限的物理资源强制行驶多用户共享,消除计算机部件之间的乎等现象,以提高系统资源利用率。

操作系统实验报告(进程的创建)(DOC)

实验题目进程的创建小组合作否姓名班级学号 一、实验目的 1、了解进程的创建。 2、了解进程间的调用以及实现。 3、分析进程竞争资源的现象,学习解决互斥的方法。 4、加深对进程概念的理解,认识并发执行的本质。 二.实验环境 Windows 系统的计算机一台,安装了Linux虚拟机 三、实验内容与步骤 1、fork()系统调用的使用例子 程序代码: #include #include #include int glob=3; int main(void) { pid_t pid;int loc=3; printf("before fork();glod=%d,loc=%d.\n",glob,loc); if((pid=fork())<0) { printf("fork() error. \n"); exit(0); } else if(pid==0) { glob++; loc--; printf("child process changes glob and loc: \n"); } else

wait(0); printf("parent process doesn't change the glob and loc:\n"); printf("glob=%d,loc=%d\n",glob,loc); exit(0); } 运行结果: 2、理解vofork()调用: 程序代码: #include #include #include int glob=3; int main(void) { pid_t pid; int loc=3; if((pid=vfork())<0) { printf("vfork() error\n"); exit(0); } else if(pid==0) { glob++; loc--; printf("child process changes the glob and loc\n"); exit(0); } else printf ("parent process doesn't change the glob and loc\n"); printf("glob=%d,val=%d\n",glob,loc);

Linux的fork、exec、wait函数的分析

Linux 的fork 、exec 、wait 函数分析 I 数学与计算机学院 课程设计说明书 课 程 名 称: 操作系统原理-课程设计 课 程 代 码: 8404061 题 目: Linux 的fork 、exec 、wait 函数的分析 年级/专业/班: 学 生 姓 名: 学 号: 3 开 始 时 间: 2010 年 12 月 12 日 完 成 时 间: 2011 年 01 月 09 日 课程设计成绩: 指导教师签名: 年 月 日

Linux 的fork 、exec 、wait 函数分析 II 目 录 1 引 言 ................................................................. 1 1.1 问题的提出 ...................................................................................................................... 1 1.2国内外研究的现状 ........................................................................................................... 1 1.3任务与分析 ....................................................................................................................... 1 2代码分析结果 ............................................................ 2 2.1 数据结构 ......................................................................................................................... 2 2.1.1 struct task_struct ............................................................................................. 2 2.1.2 task ......................................................................................................................... 3 2.1.3 tarray_freelist ................................................................................................... 3 2.1.4 struct--linux_binprm ......................................................................................... 3 2.1.5进程状态 .................................................................................................................. 4 2.2常量和出错信息的意义 .................................................................................................. 4 2.3调用关系图 ...................................................................................................................... 4 2.4各模块/函数的功能及详细框图 .................................................................................... 5 2.4.1 do_fork 模块 .......................................................................................................... 5 2.4.2 get_pid 模块 .......................................................................................................... 8 2.4.3 do_execve 模块 ........................................................................................................ 10 3.4.4 do_exit 模块 ........................................................................................................ 14 3.4.5 sys_wait4模块 .................................................................................................. 18 3 总结与体会 ............................................................ 20 4 参考文献 .. (20)

操作系统进程控制

操作系统课程设计实验报告 实验名称:进程控制 姓名/学号:xx 20091758 一、实验目的 设计并实现Unix的“time”命令。“mytime”命令通过命令行参数接受要运行的程序,创建一个独立的进程来运行该程序,并记录程序运行的时间。 二、实验内容 一、在Windows下实现: ?使用CreateProcess()来创建进程 ?使用WaitForSingleObject()在“mytime”命令和新创建的进程之间同步 ?调用GetSystemTime()来获取时间 在Linux下实现: ?使用fork()/execv()来创建进程运行程序 ?使用wait()等待新创建的进程结束 ?调用gettimeofday()来获取时间 mytime的用法: $ mytime.exe program1 三、实验环境 操作系统:Windows7旗舰版 处理器:Intel Core2 Duo p7450 2.13GHz 内存:2.00GB 32位操作系统 LINUX版本信息:Linux ubuntu 2.6.32-21-generic #32-Ubuntu SMP Fri Apr 16 08:10:02 UTC 2010 i686 GNU/Linux

四、程序设计与实现 一.windows下的实验 1、创建进程之前先用系统函数getsystemtime获取当前时间。 SYSTEMTIME systime; GetSystemTime(&systime); 2、调用createprocess函数创建进程: BOOL bRet = CreateProcess( NULL, //不在此指定可执行文件的文件名 argv[1], //命令行参数 NULL, //默认进程安全性 NULL, //默认线程安全性 FALSE, //当前进程内的句柄不可以被子进程继承 CREATE_NEW_CONSOLE, //为新进程创建一个新的控制台窗口 NULL, //使用本进程的环境变量 NULL, //使用本进程的驱动器和目录 &si, //父进程传给子进程的一些信息 &pi); //保存新进程信息的结构 由于要使用命令行来创建进程,,所以我的createprocess函数第一个参数设置为NULL,通过第二个参数在命令行里实现创建进程。 3、使用等待函数来等待所创建进程的死亡。 WaitForSingleObject(pi.hProcess,INFINITE); 4、再次取得系统当前时间,与上次取得时间作差,得到进程运行时间。 具体做法是:将两次时间对应位作差,然后换算成相应秒数。 t=(systime.wHour-h)*3600+(systime.wMinute-m)*60+systime.wSecond-s+(systime.w Milliseconds-ms)/1000; 二.Linux下的实验 1、创建进程之前先得到系统时间 struct timeval start; struct timeval end; gettimeofday(&start,NULL); 2、用fork函数创建进程,这时函数会返回两个值,需要通过返回值来判断是子进程还 是父进程。 pc = fork(); if ( pc < 0 ) /* 如果出错*/ { exit(1); } else if ( pc == 0) /* 如果是子进程*/ {……} else /* 如果是父进程*/ {……}

进程创建之fork系统调用

4 进程创建 (1) 4.1 实验内容及要求 (1) 4.2 实验目的 (1) 4.3 实验环境 (1) 4.4 实验思路 (1) 4.5 实验代码 (2) 4.6 运行结果 (3) 4.7 实验心得 (3) 4 进程创建 4.1 实验内容及要求 利用fork()系统调用创建进程。要求如下: 编制一段程序,使用系统调用fork( )创建两个子进程,这样在此程序运行时,在系统中就有一个父进程和两个子进程在活动。每一个进程在屏幕上显示一个字符,其中父进程显示字符A,子进程分别显示字符 B和字符C。试观察、记录并分析屏幕上进程调度的情况。 4.2 实验目的 了解进程的创建过程,进一步理解进程的概念,明确进程和程序的区别。 4.3 实验环境 Ubuntu 18.04.1 LTS 64位,编译器gcc 7.3.0 (Ubuntu 7.3.0-16ubuntu3) 4.4 实验思路 (1)可用fork()系统调用来创建一个新进程。 系统调用格式:pid=fork() fork()返回值意义如下: =0:若返回值为0,表示当前进程是子进程。 >0:若返回值大于0,表示当前进程是父进程,返回值为子进程的pid值。

<0:若返回值小于0,表示进程创建失败。 如果fork()调用成功,它向父进程返回子进程的pid,并向子进程返回0,即fork()被调用了一次,但返回了两次。此时OS在内存中建立一个新进程,所建的新进程是调用fork()父进程的副本,称为子进程。子进程继承了父进程的许多特性,并具有与父进程完全相同的用户级上下文。父进程与子进程并发执行。 (2)编译和执行的方法: 编译:在shell提示符下输入gcc 源文件名 -o 可执行文件名 运行:在shell提示符下输入 ./可执行文件名 4.5 实验代码 #include #include #include int main(void) { pid_t p1=fork();pid_t p2=fork(); //迭代调用fork(),创建三个新进程printf("this is parent, pid = %d\n", getpid()); //父进程 if(p1<0||p2<0){ //fork()失败 printf("fork failed with p1=%d, p2=%d\n", p1, p2); exit(1); }if(p1==0&&p2==0){ //子进程B创建的子进程D,即孙进程 printf("D in grandson Damson, pid = %d\n", getpid()); }if(p1==0&&p2>0){ //父进程创建的子进程B printf("B in child Blueberry, pid = %d\n", getpid()); }if(p1>0&&p2==0){ //父进程创建的子进程C printf("C in child Carambola, pid = %d\n", getpid()); }if(p1>0&&p2>0){ //父进程 printf("A in parent Apple, pid = %d\n", getpid()); }return 0; }

最新Linux多进程并发执行实验

一、实验目的 1 2 1、对理论课中学习的进程、程序等的概念作进一步的理解,明确进程和程序3 的区别; 2、加深理解进程并发执行的概念,认识多进程并发执行的实质; 4 5 3、观察进程争夺资源的现象,分析其过程和原因,学习解决进程互斥的方法;6 4、对经典的多用户、多任务的优先级轮转调度系统Linux有一定的了解; 7 5、了解Linux系统中多进程之间通过管道通信的基本原理和应用方法。 8 9 二、实验内容 10 1、用virtual虚拟机运行linux虚拟系统; 11 2、分析并理解源程序; 12 3、在linux中输入相应程序并观察运行结果。 13 14 三、实验原理 15 (一)多进程并发执行是使用后台任务来实现任务的“多进程化”。在不加控16 制的模式下,不管有多少任务,全部都后台执行。也就是说,在这种情况下,有17 多少任务就有多少“进程”在同时执行。 18 (二)实验中要用到的函数 19 1、fork()函数——进程创建函数。

2、getpid()函数——取得目前进程的进程标识码。 20 21 3、exit()函数——用来正常终结目前进程的执行。 22 4、sleep()函数——用来延时,它会被挂起,把处理器让给其他的进程。 23 5、printf()函数——是格式化输出函数, 一般用于向标准输出设备按规24 定格式输出信息。 25 (三)实验中要用的命令 1、cd 命令: 26 27 功能:改变工作目录。 28 语法:cd [directory] 说明:该命令将当前目录改变至directory所指定的目录。若没有指定 29 30 directory,则回到用户的主目录。为了改变到指定目录,用户必须拥有对指定31 目录的执行和读权限。该命令可以使用通配符。 32 2、mkdir命令: 33 功能:创建一个目录(类似MSDOS下的md命令)。 34 语法:mkdir [选项] dir-name 35 说明:该命令创建由dir-name命名的目录。要求创建目录的用户在当前目录36 中(dir-name的父目录中)具有写权限,并且dirname不能是当前目录中已有37 的目录或文件名称。 38 3、ls 命令: 功能:ls是英文单词list的简写,其功能为列出目录的内容。这是用户最常 39 40 用的一个命令之一,因为用户需要不时地查看某个目录的内容。该命令类似于

fock()函数问题

#include #include #include int main() { pid_t pid1; pid_t pid2; pid1 = fork(); pid2 = fork(); printf("pid1:%d, pid2:%d\n", pid1, pid2); } 输出: pid1:3411, pid2:3412 pid1:0, pid2:3413 pid1:3411, pid2:0 pid1:0, pid2:0 1. 基础知识: 1)fork函数总是“调用一次,返回两次”,在父进程中调用一次,在父进程和子进程中各返回一次。fork在子进程中的返回值是0,而在父进程中的返回值则是子进程的id。 2)子进程在创建的时候会复制父进程的当前状态(PCB信息相同,用户态代码和数据也相同)。 3)程序运行的结果基本上是父子进程交替打印,但这也不是一定的,取决于系统中其它进程的运行情况和内核的调度算法。 2. 第一个fork: 子进程A被创建,之后从fork函数往下执行与父进程相同的代码,即后一个fork和printf 会被父进程和子进程A分别执行一次: 父进程打印的pid1和pid2是两个子进程的pid,即结果的第一行:pid1:3411, pid2:3412 子进程A打印的pid1和pid2是这个fork在子进程A中的返回(0)和子进程A中调用fork返回的pid,即结果的第二行:pid1:0, pid2:3413 3. 第二个fork: 这个fork会被父进程和子进程A都执行一遍。假设子进程B被主进程创建,子进程C被子进程A创建。子进程A也可以说是子进程C的父进程,为了避免混淆,我这里改叫主进程而不再使用父进程的概念。 子进程B的打印即结果的第三行:pid1:3411, pid2:0。其中,其中,pid1为复制的主进程的数据,pid2为该fork在子进程B中的返回。 子进程C的打印,即结果的最后一行:pid1:0, pid2:0。其中,pid1为复制的进程A的数据,pid2为该fork在子进程C内部的返回。

相关文档
最新文档