操作系统实验-第三讲-进程的创建
操作系统实验报告--进程的创建
{
printf("父进程id=%d,父进程打印a\n",getpid());
exit(0);
}
}
随机执行:
程序执行如下:
1.父进程里的fork调用,复制父进程生成一个副本即为子进程1
2.得到父进程与子进程1
3.随机执行这两进程中的一个,(两个进程都是压在栈里)
4.假设(那么栈底下的就是父进程)执行的是子进程1,则fork返回值是0,则for循环中断!这是也是子进程不能创建自己的子子进程的一个重点!i=0,往下继续执行当前进程的后面的程序,打印当前子进程1的信息,并且按照要求打印出b。这个进程执行完毕后自动销毁!
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)
{
break;
}
}
if(pid==-1)
{
perror("fail to fork!\n");
exit(1);
}
else if(pid==0)
{
printf("子进程%did=%d,打印%c,其对应的父进程id=%d\n",i+1,getpid(),98+i,getppid());
exit(0);
}
源代码:
#include<stdio.h>
#include<unistd.h>
进程的创建实验报告
进程的创建实验报告进程的创建实验报告引言:在计算机科学领域中,进程是一个非常重要的概念。
进程是计算机程序的执行实例,它具有独立的内存空间和执行环境。
进程的创建是操作系统中一个关键的操作,本实验旨在通过编写一个简单的程序来演示进程的创建过程。
实验目的:通过实验,我们的目标是深入理解进程的创建过程,并了解操作系统是如何管理进程的。
实验步骤:1. 引入必要的头文件:在开始编写代码之前,我们需要引入一些必要的头文件。
这些头文件包括<sys/types.h>、<sys/wait.h>和<unistd.h>。
这些头文件提供了创建进程所需的函数和数据类型。
2. 创建一个子进程:在主程序中,我们使用fork()函数来创建一个子进程。
fork()函数会在当前进程的基础上创建一个新的进程,这个新进程称为子进程。
子进程和父进程几乎完全相同,只有在返回值上有所区别。
如果fork()函数返回0,表示当前进程是子进程;如果返回一个正整数,表示当前进程是父进程。
3. 子进程的执行:在子进程中,我们可以编写任意的代码来执行特定的任务。
子进程可以使用exec()函数来执行其他程序,或者执行一系列的操作。
在本实验中,我们简单地输出一条信息,以展示子进程的执行过程。
4. 父进程的执行:在父进程中,我们可以编写代码来执行其他任务,或者等待子进程的结束。
在本实验中,我们使用wait()函数来等待子进程的结束。
wait()函数会暂停父进程的执行,直到子进程结束为止。
5. 编译和运行程序:在完成代码编写后,我们需要将程序编译成可执行文件,并运行它。
我们可以使用gcc编译器来编译程序,然后运行生成的可执行文件。
实验结果:在运行程序后,我们可以观察到以下结果:子进程开始执行。
父进程等待子进程结束。
子进程结束。
父进程继续执行。
结论:通过本实验,我们成功地演示了进程的创建过程。
我们了解了操作系统是如何管理进程,并且掌握了使用fork()函数来创建子进程的方法。
操作系统实验3进程的创建控制实验
操作系统实验3进程的创建控制实验实验三的目标是通过实现一个进程控制程序,来加深我们对进程创建和控制机制的理解,并通过实践来熟悉和掌握相关的编程技巧。
在进行实验之前,我们需要先了解进程的一些基本概念和相关知识。
首先,进程的创建是通过操作系统中的系统调用来完成的。
在Linux系统中,常用的创建进程的系统调用有fork(和exec(。
fork(系统调用可以创建一个新的进程,该进程与调用fork(的进程几乎完全相同;而exec(系统调用则在新创建的进程中执行一个新的程序。
另外,进程的控制机制主要是通过进程的状态来实现的。
进程可以处于就绪状态、运行状态和阻塞状态。
就绪状态的进程可以被调度器选择后立即运行,而阻塞状态的进程则需要等待一些条件满足后才能被唤醒并变为就绪状态。
实验三的具体内容包括:1. 编写一个程序,通过调用fork(创建多个子进程。
子进程和父进程可以并行执行,共享程序的代码和数据段。
2. 子进程通过调用exec(系统调用执行不同的程序。
可以通过调用不同的exec(函数或者传入不同的参数来执行不同的程序。
3. 子进程执行的程序可能会产生不同的结果,比如输出不同的字符串或者产生不同的返回值。
我们可以通过wait(系统调用等待子进程退出,并获取子进程的返回值。
4. 父进程可以通过调用waitpid(系统调用来选择等待一些特定的子进程,以及获取特定子进程的返回值。
通过实验三的实践,我将更加深入地了解进程的创建和控制机制。
实验三的实验结果将让我熟悉和掌握相关的编程技巧,为我今后更加熟练地编写和控制进程打下坚实的基础。
总之,实验三是一个非常有意义的实验,将帮助我更加深入地理解进程的创建和控制机制,并通过实践获得相关的编程技巧。
这将对我今后的学习和实践有很大的帮助。
实验三进程的创建和简单控制
浙江大学城市学院实验报告课程名称操作系统原理实验实验项目名称实验三进程的创建和简单控制学生姓名专业班级学号实验成绩指导老师(签名)日期一. 实验目的和要求1.掌握进程的概念和进程的状态,对进程有感性的认识;2.掌握进程创建方法;3.认识进程的并发执行,了解进程族之间各种标识及其存在的关系;4.熟悉进程的创建、阻塞、唤醒、撤销等控制方法。
二、实验内容1.了解有关Linux进程的属性和进程的层次结构;2.学习有关Linux的前台和后台进程;3.学习有关Linux命令的顺序执行和并发执行;4.学习有关挂起和终止进程;5.了解并发程序的不可确定性,进行简单并发程序设计。
三、实验步骤(一)Shell下的进程控制1、用ps查看进程。
查看ps命令的帮助文件,尝试不同的参数,并观察结果ps –help查看更多ps的参数ps –A 列出所有的进程ps –au 显示较详细的信息USER 进程创建者的用户名PID 进程的ID号%CPU 进程占用的CPU百分比%MEN 进程占用内存的百分比VSZ 进程占用虚拟内存的大小RSS 内存中页的数量(页是管理内存的单位,在PC上通常为4K)TTY 进程所在终端的ID号STAT 进程的状态START 进程启动的时间TIME 进程已经占用的CPU时间COMMAND 命令和参数ps –aux 显示所有包含其他使用者的进程注:top命令即时跟踪进程信息观察了下大概是5s更新一次使用CPU最多的程序排在最前面。
最后用q命令退出这个监视程序。
2、kill命令使用3、pstree命令使用显示系统中进程的层次结构(二)Linux简单进程编程每个步骤请运行程序、截图,并解释运行结果,回答实验指导书的问题。
1、i先执行子进程,最后执行父进程,代表程序运行结束ii2个子进程分别执行一次,然后P1子进程执行一次,接着父进程执行,代表P1进程结束。
P2子进程执行,父进程再执行,代表P2结束。
iP1进程先执行,然后P2进程执行,最后父进程执行ii由于函数printf( )在输出字符串时不会被中断,因此,字符串内部字符顺序输出不变iii3、每次执行的进程号都改变iisleep(1)延长进程执行的时间删除sleep(1)后:iii删除wait()后:父子进程交替执行。
实验3:进程的创建
一、实验目的1.了解进程与程序的区别,加深对进程概念的理解。
2.掌握进程并发执行的原理,理解进程并发执行的特点,区分进程并发执行与串行执行。
3.了解fork()系统调用的返回值,掌握用fork()创建进程的方法。
4.熟悉wait,exit等系统调用。
二、实验要求1、实验程序一的要求1)编写一C语言程序(以自己的姓名拼音或者学号命名),实现在程序运行时通过系统调用fork()创建两个子进程,使父、子三进程并发执行,父亲进程执行时屏幕显示“parent”,儿子进程执行时屏幕显示“son”,女儿进程执行时屏幕显示“daughter”。
在执行进程的同时,打印各个进程的ID号(提示:调用getpid())。
2)多次连续反复运行这个程序(提示:可设置循环,让已被创建的子进程作为父进程,继续创建子进程),观察屏幕显示结果的顺序,直至出现不一样的情况为止。
记下这种情况,试简单分析其原因。
3)能够查看你的程序所创建的进程的详细信息(提示:ps命令+参数)。
并能够以树形结构(提示:pstree命令)显示你所创建的进程的父子关系(提示:若在实验程序一运行结束后再查看进程,则无法显示程序一中创建的进程,所以只能在程序一运行期间,查看当前进程)。
4)经过GCC编译的可执行的目标文件要重命名为以自己姓名的拼音为文件名,不能以a.out为文件名2、实验程序二的要求1)会使用wait、exit等系统调用“实现”其同步推进,多次反复运行改进后的程序,观察并记录运行结果。
修改该参考程序,使得系统创建进程不成功。
2)能够查看系统中目前的所有进程,并能够撤销某个进程。
请用截图表明撤销成功。
3)经过GCC编译的可执行的目标文件要重命名为以自己姓名的拼音为文件名,不能以a.out为文件名三、实验指导1.fork()系统调用创建一个新进程。
系统调用格式:pid=fork()参数定义:int fork()fork()返回值意义如下:0:在子进程中,pid变量保存的fork()返回值为0,表示当前进程是子进程。
操作系统实验报告(进程的创建)
操作系统实验报告(进程的创建)
1、
四、实验过程与分析
1、在1例子中,调用正确完成时,给父进程返回的是被创建子进程标识,给子进程自己返回的是0;创建失败时,返回给父进程的是-1。
2、在2例子中,vfork()调用后需要注意两点:
(1)子进程先运行,父进程挂起。
子进程调用exec()或exit()之后。
父进程的执行顺序不再有限制。
(2)子进程在调用exec()或exit()之前。
父进程被激活,就会造成死锁。
3、在6例子中,上述程序是父进程先创建一个子进程,若成功,再创建另一个子进程,之后三个进程并发执行。
究竟谁先执行,是随机的。
所以执行结果有多重种。
五、实验总结
1、一个进程调用exec()函数来运行一个新程序。
之后该进程的代码段、数据段和堆栈段就被新程序的所代替。
新程序从自己的main()函数开始执行。
exec()函数有6种不同的形式,任何一个都可以完成exec()的功能,只是调用参数不同。
2、在父子进程同步中,当一个进程结束时,产生一个终止状态字,然后核心发一个SIGCHLD信号通知父进程。
因为子进程结束是异步于父进程的,故父进程要结束之前,要同步等待子进程终止。
这是通过调用系统调用wait或waitpid来实现的。
当父进程通过调用wait或waitpid同步等待子进程结束时,可能有以下几种情况:
(1)如果子进程还未结束,父进程阻塞等待;
(2)如果子进程已经结束,其终止状态字SIGCHLD放在指定位置等待父进程提取,这时,父进程可立即得到终止状态字并返回;
(3)如果没有子进程,父进程立即错误并返回。
实验三 进程的创建和简单控制
实验三进程的创建和简单控制实验目的:1. 掌握进程的概念和进程的状态,对进程有感性的认识;2. 掌握进程创建方法;3. 认识进程的并发执行,了解进程族之间各种标识及其存在的关系;4. 熟悉进程的创建、阻塞、唤醒、撤销等控制方法。
实验内容:1. 了解有关Linux进程的属性和进程的层次结构;2. 学习有关Linux的前台和后台进程;3. 学习有关Linux命令的顺序执行和并发执行;4. 学习有关挂起和终止进程;5. 了解并发程序的不可确定性,进行简单并发程序设计。
实验步骤:(一)Shell 下的进程控制1. 进入Linux系统。
2. 用ps查看进程。
a) linux的ps命令是用来监视系统进程和资源使用情况的命令,可显示瞬间进程的动态。
b) ps 的参数非常多,常用的参数有:i. -A 列出所有的进程;ii. -w 显示加宽可以显示较多的信息;iii. -au 显示较详细的信息;iv. -aux 显示所有包含其他使用者的进程。
3. 用kill终止某些进程。
a) kill命令通过向进程发送指定的信号来结束进程。
b) 先使用ps查到进程号,再使用kill杀出进程。
4. 用pstree命令显示系统中进程层次结构。
PDF 文件使用 "pdfFactory Pro" 试用版本创建a) pstree指令用ASCII字符显示树状结构,清楚地表达进程间的相互关系。
b) 语法格式pstree [-acGhlnpuUV][-H <程序识别码>][<程序识别码>/<用户名称>](二)Linux 简单进程编程1. 理解系统调用fork()的使用。
a) fork()会产生一个与父程序相同的子程序,唯一不同之处在于其进程号。
图2 系统调用fork()b) 编辑下面的程序,如图3所示,要求实现父进程产生两个子进程,父进程显示字符“a”、两个子进程,分别显示字符“b”、“c”。
实验三 进程的创建实验
实验三进程的创建实验[实验目的及要求]1.掌握进程的概念,明确进程的含义;2.认识并了解并发执行的实质;3.理解LINUX下进程创建的基本方法和过程。
[实验原理]一、进程UNIX中,进程既是一个独立拥有资源的基本单位,又是一个独立调度的基本单位。
一个进程实体由若干个区(段)组成,包括程序区、数据区、栈区、共享存储区等。
每个区又分为若干页,每个进程配置有唯一的进程控制块PCB,用于控制和管理进程。
PCB的数据结构如下:1.进程表项(Process Table Entry)。
包括一些最常用的核心数据:进程标识符PID、用户标识符UID、进程状态、事件描述符、进程和U区在内存或外存的地址、软中断信号、计时域、进程的大小、偏置值nice、指向就绪队列中下一个PCB 的指针P_Link、指向U区进程正文、数据及栈在内存区域的指针。
2.U区(U Area)。
用于存放进程表项的一些扩充信息。
每一个进程都有一个私用的U区,其中含有:进程表项指针、真正用户标识符u-ruid(read user ID)、有效用户标识符u-euid(effective user ID)、用户文件描述符表、计时器、内部I/O参数、限制字段、差错字段、返回值、信号处理数组。
由于UNIX系统采用段页式存储管理,为了把段的起始虚地址变换为段在系统中的物理地址,便于实现区的共享,所以还有:3.系统区表项。
以存放各个段在物理存储器中的位置等信息。
系统把一个进程的虚地址空间划分为若干个连续的逻辑区,有正文区、数据区、栈区等。
这些区是可被共享和保护的独立实体,多个进程可共享一个区。
为了对区进行管理,核心中设置一个系统区表,各表项中记录了以下有关描述活动区的信息:区的类型和大小、区的状态、区在物理存储器中的位置、引用计数、指向文件索引结点的指针。
4.进程区表系统为每个进程配置了一张进程区表。
表中,每一项记录一个区的起始虚地址及指向系统区表中对应的区表项。
计算机操作系统实训教程之进程的创建实验报告
计算机操作系统实训教程实验报告姓名王学杰专业计算机应用技术班级班课程操作系统实验项目进程的创建【实验目的】.加深对进程、进程树等概念的理解。
.进一步明确进程和程序的区别。
.理解进程并发执行的实质。
.掌握系统中进程的创建方法及并发执行的情况。
【实验内容】.编写一段程序,使用系统调用()创建两个子进程。
当此程序运行时,在系统中有一个父进程和两个子进程活动。
让每一个进程在屏幕上显示一段字符信息。
.学习对后台执行程序的控制方式。
.分析程序执行过程中产生的子进程情况。
【实验步骤】一、、编写源代码生成源文件“$ ”。
.编译“$ –”。
.前台运行“$ ”(按组合键终止死循环的程序)。
.多次使用–命令查看进程状态。
.使用命令控制该进程。
二、编写源代码生成源文件“”。
.编译源文件生成可执行程序“”:“$ –”。
.后台运行“$ ”。
.查看进程树“$ ”。
三例编写源代码生成源文件“”。
.编译源文件生成可执行程序“”:“$ –”。
.运行“$ ”。
四编写源代码生成源文件“”。
.编译源文件生成可执行程序“”:“$ –”。
.运行“$”。
五编写源代码生成源文件“”。
.编译源文件生成可执行程序“”:“$ –”。
运行结果如下【实验总结】一、入门知识一个进程,包括代码、数据和分配给进程的资源。
()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
一个进程调用()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。
然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。
相当于克隆了一个自己。
调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:)在父进程中,返回新创建子进程的进程;)在子进程中,返回;)如果出现错误,返回一个负值;二、()与()区别()与()都是创建一个进程,那他们有什么区别呢?总结有以下三点区别:. ():子进程拷贝父进程的数据段,堆栈段():子进程与父进程共享数据段. ()父子进程的执行次序不确定保证子进程先运行,在调用或之前与父进程数据是共享的,在它调用或之后父进程才可能被调度运行。
实验三 进程的创建
实验报告
学院:专业:班级:
运行
)系统是怎样创建进程的?
答:进程创建方式主要有两种,一是由系统程序模块统一创建,例如在批处理系统中,由操作系统的作业调度程序为用户作业创建相应的进程以完成用户作业所要求的功能。
二是由父进程创建,例如在层次结构的系统中,父进程创建子进程以完成并行工作。
)当首次调用新创建进程时,其入口在哪里?
答:由fork() 系统调用创建的新进程被称为子进程。
该函数被调用一次,但返回两次。
如果fork()进程调用成功,两次返回的区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程号。
其入口在进程队列的ready状态下,由离自己最近的父进程执行调度,即入口在最近的父进程处。
操作系统实验报告(进程的创建).doc
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<stdio.h>#include<sys/types.h>#include<unistd.h>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);}elseprintf ("parent process doesn't change the glob and loc\n");printf("glob=%d,val=%d\n",glob,loc);}运行结果:3、给进程指定一个新的运行程序的函数exec().程序代码:printe1.c代码:#include<stdio.h>int main(int argc,char * argv[]){int n;char * * ptr;extern char * * environ;for(n=0;n<argc;n++)printf("argv[%d]:%s\n",n,argv[n]);for(ptr=environ; * ptr!=0;ptr++)printf("%s\n",* ptr);exit(0);}file4.c代码如下:#include<stdio.h>#include<sys/types.h>#include<unistd.h>#include<sys/wait.h>char * env_list[]={"USER=root","PATH=/root/",NULL};int main(){pid_t pid;if((pid=fork())<0){printf("fork error!\n");exit(0);}else if(pid==0){if(execle("/root/print1","print1","arg1","arg2",(char *)0,env_list)<0) printf("execle error!\n");exit(0);}if((waitpid(pid,NULL,0))<0)printf("WAIT ERROR!\n");exit(0);if((pid=fork())<0){printf("fork error!\n");exit(0);}else if(pid==0){if(execlp("print1","print1","arg1",(char *)0)<0)printf("execle error!\n");exit(0);}exit(0);}运行结果:4、进程终止函数exit()。
进程的创建实验报告
一、实验目的1. 理解进程的概念及其在操作系统中扮演的角色。
2. 掌握在特定编程环境中创建进程的方法。
3. 分析进程创建的过程和机制。
4. 熟悉进程间通信和同步的基本原理。
二、实验环境1. 操作系统:Windows 102. 编程语言:C/C++3. 开发工具:Visual Studio 2019三、实验原理进程是操作系统中执行的基本单元,是系统进行资源分配和调度的基本单位。
在操作系统中,进程的创建是系统调用的过程,通过系统调用,父进程可以创建子进程。
在创建子进程时,子进程将继承父进程的某些属性,如环境变量、打开的文件等。
四、实验步骤1. 创建父进程- 编写一个简单的C/C++程序,使用`fork()`系统调用创建子进程。
2. 创建子进程- 在父进程中,通过`fork()`函数创建子进程。
`fork()`函数返回值有以下几种情况:- 返回0:表示子进程;- 返回子进程的进程ID:表示父进程;- 返回-1:表示创建子进程失败。
3. 父进程和子进程的区分- 通过检查`fork()`的返回值,父进程和子进程可以相互区分。
父进程可以通过返回值获取子进程的进程ID。
4. 父进程和子进程的通信- 使用管道(pipe)实现父进程和子进程之间的通信。
创建管道后,父进程通过管道向子进程发送数据,子进程从管道中读取数据。
5. 父进程和子进程的同步- 使用互斥锁(mutex)和条件变量(condition variable)实现父进程和子进程的同步。
父进程在完成工作后,可以通知子进程继续执行。
五、实验代码```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/wait.h>#include <fcntl.h>int main() {int pipe_fd[2];pid_t pid;// 创建管道if (pipe(pipe_fd) == -1) {perror("pipe");exit(EXIT_FAILURE);}// 创建子进程pid = fork();if (pid == -1) {perror("fork");exit(EXIT_FAILURE);}if (pid == 0) {// 子进程close(pipe_fd[1]); // 关闭管道的写端dup2(pipe_fd[0], STDIN_FILENO); // 将管道的读端复制到标准输入execlp("date", "date", NULL); // 执行date命令} else {// 父进程close(pipe_fd[0]); // 关闭管道的读端write(pipe_fd[1], "Hello, world!\n", 15); // 向管道写入数据close(pipe_fd[1]); // 关闭管道的写端wait(NULL); // 等待子进程结束printf("Child process exited with PID %d\n", pid);}return 0;}```六、实验结果与分析1. 父进程和子进程分别运行`date`命令和输出“Hello, world!”字符串。
操作系统实验报告(进程的创建)范文
实验题目进程的创建小组合作否姓名班级学号一、实验目的1、了解进程的创建。
2、了解进程间的调用以及实现。
3、分析进程竞争资源的现象,学习解决互斥的方法。
4、加深对进程概念的理解,认识并发执行的本质。
二.实验环境Windows 系统的计算机一台,安装了Linux虚拟机三、实验内容与步骤1、fork()系统调用的使用例子程序代码:#include<stdio.h>#include<sys/types.h>#include<unistd.h>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");}elsewait(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<stdio.h>#include<sys/types.h>#include<unistd.h>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);}elseprintf ("parent process doesn't change the glob and loc\n");printf("glob=%d,val=%d\n",glob,loc);}运行结果:3、给进程指定一个新的运行程序的函数exec().程序代码:printe1.c代码:#include<stdio.h>int main(int argc,char * argv[]){int n;char * * ptr;extern char * * environ;for(n=0;n<argc;n++)printf("argv[%d]:%s\n",n,argv[n]);for(ptr=environ; * ptr!=0;ptr++)printf("%s\n",* ptr);exit(0);}file4.c代码如下:#include<stdio.h>#include<sys/types.h>#include<unistd.h>#include<sys/wait.h>char * env_list[]={"USER=root","PATH=/root/",NULL};int main(){pid_t pid;if((pid=fork())<0){printf("fork error!\n");exit(0);}else if(pid==0){if(execle("/root/print1","print1","arg1","arg2",(char *)0,env_list)<0) printf("execle error!\n");exit(0);}if((waitpid(pid,NULL,0))<0)printf("WAIT ERROR!\n");exit(0);if((pid=fork())<0){printf("fork error!\n");exit(0);}else if(pid==0){if(execlp("print1","print1","arg1",(char *)0)<0)printf("execle error!\n");exit(0);}exit(0);}运行结果:4、进程终止函数exit()。
操作系统实验---进程的创建与控制
实验报告实验题目姓名:学号:课程名称:操作系统实验所在学院:信息科学与工程学院专业班级:计算机任课教师:核心为fork( )完成以下操作:(1)为新进程分配一进程表项和进程标识符进入fork( )后,核心检查系统是否有足够的资源来建立一个新进程。
若资源不足,则fork( )系统调用失败;否则,核心为新进程分配一进程表项和唯一的进程标识符。
(2)检查同时运行的进程数目超过预先规定的最大数目时,fork( )系统调用失败。
(3)拷贝进程表项中的数据将父进程的当前目录和所有已打开的数据拷贝到子进程表项中,并置进程的状态为“创建”状态。
(4)子进程继承父进程的所有文件对父进程当前目录和所有已打开的文件表项中的引用计数加1。
(5)为子进程创建进程上、下文进程创建结束,设子进程状态为“内存中就绪”并返回子进程的标识符。
(6)子进程执行虽然父进程与子进程程序完全相同,但每个进程都有自己的程序计数器PC(注意子进程的注意子进程的PC 开始位置),然后根据pid 变量保存的fork( )返回值的不同,执行了不同的分支语句。
四、实验过程、步骤及内容1、编写一段程序,使用系统调用fork( )创建两个子进程。
当此程序运行时,在系统中有一个父进程和两个子进程活动。
让每一个进程在屏幕上显示一个字符:父进程显示'a',子进程分别显示字符'b'和字符'c'。
试观察记录屏幕上的显示结果,并分析原因。
2、修改上述程序,每一个进程循环显示一句话。
子进程显示'daughter …'及'son ……',父进程显示'parent ……',观察结果,分析原因。
3、用fork( )创建一个进程,再调用exec( )用新的程序替换该子进程的内容4、用fork( )建立如下形式的进程树:A进程B进程C进程D进程各个进程中都打印出本身PID 和其父进程的PID,并用wait( )来控制进程执行顺序,打印出正确和期望的结果。
《操作系统原理》进程的创建与管理实验
《操作系统原理》进程的创建与管理实验1.目的要求(1)加深对进程概念的理解,明确进程和程序的区别。
(2)深入了解系统如何组织进程、创建进程。
(3)进一步认识如何实现处理器调度。
2.实验内容编写程序完成单处理机系统中的进程调度,要求采用时间片轮转调度算法。
实验具体包括:首先确定进程控制块的内容,进程控制块的组成方式;然后完成进程创建原语和进程调度原语;最后编写主函数对所做工作进行测试。
3.所需实验设施设备PC、windows操作系统4.教学形式及过程演示、学生独立完成5.设计思路(1)该程序是一个简单的时间片轮转调度算法的实现。
(2)首先定义了一个进程控制块(PCB)的结构体,包含进程的名称、到达时间、需要的运行时间、剩余运行时间和当前状态等信息。
然后定义了一个创建新节点的函数createNode,用于动态分配内存并初始化节点的数据。
接着定义了一个向循环链表中插入新节点的函数insertNodes,根据用户的输入创建新节点并插入到链表末尾。
然后定义了一个打印链表的函数printList,用于输出链表中所有节点的信息。
(3)接下来是冒泡排序函数bubbleSort,按照到达时间对链表中的节点进行排序。
然后定义了一个运行函数run,根据时间片大小依次运行进程,直到所有进程都完成运行。
最后在主函数中读取用户输入的进程数量和时间片大小,创建链表并调用run函数进行进程调度。
(4)整体思路是:先创建一个空链表,然后根据用户输入的进程数量,逐个创建新节点并插入到链表末尾。
然后对链表中的节点按照到达时间进行排序。
接着按照时间片大小依次运行进程,直到所有进程都完成运行。
最后输出链表中所有节点的信息。
6.知识原理操作系统通过进程控制块(PCB)来组织和管理进程。
(1)首先,操作系统会为每个进程创建一个PCB,PCB中包含了进程的重要信息,如进程号、进程状态、程序计数器、寄存器值、内存分配情况、打开文件等。
(2)当一个进程被创建时,操作系统会为其分配一个唯一的进程号,并将进程的相关信息填充到PCB中。
实验3 创建进程
实验三创建进程实验目的:1、通过创建进程和观察正在运行的进程的的设计和调试操作,进一步熟悉操作系统的进程概念,理解windows进程的“一生”。
2、通过阅读和分析实验程序,学习创建进程、观察进程的程序设计方法。
实验内容:一、创建进程本实验显示了创建子进程的基本框架。
该程序只是再一次地启动自身,显示它的系统进程ID和它在进程列表中的位置。
步骤1:登录进入Windows步骤2:在“开始”菜单中单击“程序”-“Microsoft Visual Studio 6.0”–“Microsoft Visual C++ 6.0”命令,进入Visual C++窗口,选择菜单“文件/新建/c++ source File,文件名为自己的学号,进入编程界面。
步骤3:将以下程序输入# include <windows.h># include <iostream.h># include <stdio.h>void StartClone(int nCloneID){TCHAR szFilename[MAX_PATH];GetModuleFileName(NULL,szFilename,MAX_PATH);TCHAR szCmdLine[MAX_PATH];sprintf(szCmdLine,"\"%s\" %d",szFilename,nCloneID);STARTUPINFO si;ZeroMemory(reinterpret_cast<void*>(&si),sizeof(si));si.cb=sizeof(si);PROCESS_INFORMATION pi;BOOL bCreateOK=CreateProcess(szFilename, //exe文件名szCmdLine, //命令行NULL, //默认的进程安全性NULL, //默认的线程安全性FALSE, //不继承句柄CREATE_NEW_CONSOLE, //使用新的控制台NULL, //新的环境NULL, //当前目录&si, //启动信息&pi); //返回的进程信息if(bCreateOK){CloseHandle(pi.hProcess );CloseHandle(pi.hThread);}}int main(int argc,char *argv[]){int nClone(0);if(argc>1){sscanf(argv[1],"%d",&nClone);}printf("process ID: %d,Clone ID: %d\n",GetCurrentProcessId(),nClone);const int c_nCloneMax=25;if(nClone<c_nCloneMax){StartClone(++nClone);Sleep(1000);}Sleep(500);return 0;}步骤4:单击“Build”菜单中的“Compile ××.cpp”命令,系统显示:This build command requires an active project workspace. Would you like tocreate a default project workspace ?(build命令需要一个活动的项目工作空间。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统
实验报告
哈尔滨工程大学
计算机科学与技术学院
一、实验概述
1. 实验名称进程的创建
2.实验目的(1)练习使用 EOS API 函数 CreateProcess 创建一个进程,掌
握创建进程的方法,理解进程和程序的区别。
(2)调试跟踪 CreateProcess 函数的执行过程,了解进程的创
建过程,理解进程是资源分配的单位。
3. 实验类型验证型实验
4.实验内容准备实验
练习使用控制台命令创建 EOS 应用程序的进程
练习通过编程的方式让应用程序创建另一个应用程序的进程
调试 CreateProcess 函数
调试 PsCreateProcess 函数
练习通过编程的方式创建应用程序的多个进程
二、实验环境
操作系统 windos xp
编译器 OS Lab
语言 c语言
三、实验过程
1. 设计思路
创建10个进程时,可以使用 PROCESS_INFORMATION 类型定义一个有 10 个元素的数组,每一个元素对应一个进程。
使用一个循环创建 10 个子进程,然后再使用一个循环等待 10 个子进程结束,得到退出码后关闭句柄。
2. 算法实现
在创建10个进程的程序中,为了保证只有在10个进程都创建成功的情况下才执行后续操作,引入一个变量locked,只有10个程序都创建成功时locked=1,
出现创建失败的情况时locked=0,当locked=1时再执行后续操作。
3.需要解决的问题及解答
问题1:程序创建2个进程创建的情况下,实验指导P133-4的*NewProcess 和6的*ProcessObject变化情况,监控变量界面截图。
(答案见)
问题2:尝试根据之前对PsCreateProcess函数和PspCreateProcessEnvironment函数执行过程的跟踪调试,绘制一幅进程创建过程的流程图。
问题3:思考与练习,在源代码文件提供的源代码基础上进行修改,要求使用同时创建10个进程。
要给出源代码及解释和运行界面截图。
(代码见“源程序并附上注释”部分)
4. 源程序并附上注释
使用同时创建 10 个进程,代码如下:
#include""
int main(int argc,char*argv[])
{
STARTUPINFO StartupInfo;
PROCESS_INFORMATION jincheng[10];
ULONG ulExitCode; .\n\n");
n",GetLastError());
nResult=1;
locked=0;
rocessHandle,INFINITE);
}
rocessHandle,&ulExitCode);
printf("\nThe process%d exit with%d.\n",l+1,ulExitCode);
}
rocessHandle);
CloseHandle(jincheng[m].ThreadHandle);
}
}程序运行时的初值和运行结果
准备实验
建立一个EOS Kernel 项目和 EOS 应用程序项目。
练习使用控制台命令创建 EOS 应用程序的进程
将本实验文件夹中的文件拖动到FloppyImageEditor工具窗口的文件列表中释放,文件即被添加到软盘镜像文件中,按F5启动调试,在EOS的控制台中输入命令“A:\”后回车,结果如下图:
练习通过编程的方式让应用程序创建另一个应用程序的进程
使用文件中的源代码替换之前创建的 EOS 应用程序项目中的文件内的源代码,F5 启动调试,激活虚拟机窗口查看应用程序输出的内容:
调试 CreateProcess 函数
F5 启动调试 EOS 应用程序,在 main 函数中调用 CreateProcess 函数的代码行(第 57 行)添加一个断点。
按 F5 继续调试,在断点处中断。
按 F11 调试进入CreateProcess 函数。
在“调试”菜单的“窗口”中选择“反汇编”,会在“反汇编”窗口中显示 CreateProcess 函数的指令对应的反汇编代码。
“反汇编”窗口的左侧显示的是指令所在的虚拟地址。
可以看到所有指令的虚拟地址都大于 0x,说明内核()处于高 2G 的虚拟地址空间中,如图:
设置 main 函数的调用堆栈帧为活动的。
在“反汇编”窗口中查看 main 函数的指令所在的虚拟地址都是小于 0x,说明应用程序()处于低 2G 的虚拟地址空间中,如
图:
调试 PsCreateProcess 函数
在 PsCreateProcess 函数中找到调用 PspCreateProcessEnvironment 函数的代
码行(文件的第 163 行),并在此行添加一个断点。
按 F5 继续调试,到此断点处中断。
按 F11 调试进入 PspCreateProcessEnvironment 函数。
在调用 ObCreateObject 函数的代码行(文件的第 418 行)添加一个断点。
按 F5 继续调试,到此断点处中断。
按 F10 执行此函数后中断。
将表达式*NewProcess 添加到“监视”窗口中,继续一步步调试可以观察到进程控制块的成员变量的值的变化,如下图:
接下来调试初始化进程控制块中各个成员变量的过程:
当从 PspCreateProcessEnvironment 函数返回到 PsCreateProcess 函数后,停止按 F10。
此时“监视”窗口中已经不能再显示表达式*NewProcess 的值了,在PsCreateProcess 函数中是使用ProcessObject 指针指向进程控制块的,所以将表达式*ProcessObject 添加到“监视”窗口中就可以继续观察新建进程控制块中的信息。
接下来继续使用 F10 一步步调试 PsCreateProcess 函数中的代码,同样要注意进程控制块中的成员变量的变化:
练习通过编程的方式创建应用程序的多个进程
用文件中的源代码替换 EOS 应用程序项目中文件内的源代码,生成后启动调试,查看多个进程并发执行的结果。
四、实验体会
实验过程中,在调试时添加监视对象时,因为少了*导致结果不正确,后请教同学后解决了,另外在动手实现10个进程创建的问题时,一开始没有头绪,后来和原创建2个进程的程序对比以及for循环提示,写出了程序,并和同学讨论后,修正了对进程创建失败时的操作。