实验二 进程控制

合集下载

1407070225--郭飞--(二)进程的控制实验

1407070225--郭飞--(二)进程的控制实验

实验二进程管理(二)进程的控制实验一、实验目的1、掌握进程另外的创建方法2、熟悉进程的睡眠、同步、撤消等进程控制方法二、实验内容1、用fork( )创建一个进程,再调用exec( )用新的程序替换该子进程的内容2、利用wait( )来控制进程执行顺序三、实验过程进入LINUX系统。

打开虚拟机,在vi中编写程序,在终端输入文件名,执行指令,得出运行结果。

1.运行程序:2.运行实验结果:四、回答问题(1)可执行文件加载时进行了哪些处理?可执行文件加载时首先是创建一个新进程的fork系统调用,然后用于实现进程自我终止的exit系统调用;改变进程原有代码的exec系统调用;用于将调用进程挂起并等待子进程终止的wait系统调用;获得进程标识符的getpid系统调用等处理过程。

(2)什么是进程同步?wait( )是如何实现进程同步的?a.我们把异步环境下的一组并发进程因直接制约而互相发送消息、进行互相合作、互相等待,使得各进程按一定的速度执行的过程称为进程间的同步。

b.首先程序在调用fork()建立一个子进程后,马上调用wait(),使父进程在子进程调用之前一直处于睡眠状态,这样就使子进程先运行,子进程运行exec()装入命令后,然后调用wait(0),使子进程和父进程并发执行,实现进程同步。

五、实验总结通过进程创建和进程控制两节课实验,让我们掌握了进程的基本概念及其含义,了解了系统是怎样创建进程的,首次调用新进程时,其入口地址在哪,应该开始从哪执行;搞明白可执行文件加载时进行的那些处理,进一步深刻认识到进程同步的概念以及wait()实现进程同步的方式方法。

六、参考程序#include<stdio.h>#include<unistd.h>main( ){int pid;pid=fork( ); /*创建子进程*/switch(pid){case -1: /*创建失败*/printf("fork fail!\n");exit(1);case 0: /*子进程*/ execl("/bin/ls","ls","-1","-color",NULL); printf("exec fail!\n");exit(1);default: /*父进程*/ wait(NULL); /*同步*/printf("ls completed !\n");exit(0);}}。

操作系统实验二:进程管理

操作系统实验二:进程管理

操作系统实验二:进程管理操作系统实验二:进程管理篇一:操作系统实验报告实验一进程管理一、目的进程调度是处理机管理的核心内容。

本实验要求编写和调试一个简单的进程调度程序。

通过本实验加深理解有关进程控制块、进程队列的概念,并体会和了解进程调度算法的具体实施办法。

二、实验内容及要求1、设计进程控制块PCB的结构(PCB结构通常包括以下信息:进程名(进程ID)、进程优先数、轮转时间片、进程所占用的CPU时间、进程的状态、当前队列指针等。

可根据实验的不同,PCB结构的内容可以作适当的增删)。

为了便于处理,程序中的某进程运行时间以时间片为单位计算。

各进程的轮转时间数以及进程需运行的时间片数的初始值均由用户给定。

2、系统资源(r1…rw),共有w类,每类数目为r1…rw。

随机产生n进程Pi(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. 学习进程创建、撤销、阻塞和唤醒等操作。

4. 熟悉进程间的同步与通信机制。

实验环境:- 操作系统:Linux/Unix- 编程语言:C/C++- 开发工具:GCC编译器,GDB调试器实验内容:1. 创建进程:编写程序,使用系统调用fork()创建子进程,并观察父进程与子进程的行为差异。

2. 进程撤销:实现一个程序,通过系统调用exit()或abort()撤销进程,并观察其对进程组和会话的影响。

3. 进程阻塞与唤醒:设计并实现一个父进程和多个子进程的程序,其中子进程执行阻塞操作(如sleep()),父进程负责唤醒这些子进程。

4. 进程同步:利用信号量或管程等同步机制,实现两个并发进程的同步操作。

5. 进程通信:通过管道(PIPE)、消息队列、共享内存等IPC机制,实现进程间的信息交换。

实验步骤:1. 设计并编写创建进程的程序代码。

2. 在Linux环境下使用GCC编译程序,并记录编译过程。

3. 运行程序,使用GDB等工具调试程序,并观察fork()的执行效果。

4. 实现进程撤销的程序,并记录exit()和abort()的不同行为。

5. 编写进程阻塞与唤醒的程序,并通过实验观察不同进程状态的变化。

6. 完成进程同步的代码实现,并测试死锁及其解决方法。

7. 编写并测试进程通信的程序,确保信息能够正确传递。

实验结果:- 展示创建进程前后的系统状态变化,包括进程表和内存分配情况。

- 记录进程撤销后,父进程收集子进程状态的输出。

- 展示进程阻塞与唤醒的输出结果,验证进程状态转换的正确性。

- 展示进程同步的实验结果,包括死锁的产生与解决。

- 展示进程通信的测试结果,验证信息传递的准确性。

实验分析:- 分析进程创建和撤销的系统资源变化。

- 讨论进程阻塞与唤醒机制的效率和应用场景。

- 探讨进程同步与通信的复杂性及其在多线程编程中的重要性。

操作系统实验2——进程控制

操作系统实验2——进程控制

实验2 进程控制一、实验目的加深对进程概念的理解,明确进程和程序和区别;进一步认识并发执行的实质;分析进程争用资源的现象。

二、实验内容1. 熟悉Linux进程控制常用命令。

2. 输入进程创建、控制的程序并调试程序。

三、实验预备知识1. 进程控制常用命令(1)ps 命令功能:查看目前的系统中有哪些进程,以及它们的执行情况。

常用命令格式及功能如下:ps 查看系统中属于自己的进程ps au 查看系统中所有用户的进程ps aux 查看系统中包含系统内部的及所有用户的进程主要输出列说明:USER:进程所有者的用户名PID:进程号TTY:进程从哪个终端启动TIME:此进程所消耗的CPU时间COMMAND:正在执行的命令或进程名称(2)top 命令功能:动态显示进程,实时监测进程状态。

与ps命令相似,只是top命令在执行后会以指定的时间间隔来刷新显示信息,以使top所显示的进程状态总是当前时刻的。

(3)kill 命令功能:结束或终止进程。

常用命令格式及功能如下:kill 5302 杀死PID为5302的进程kill -9 5302 强行杀死PID为5302的进程(4)echo $变量名功能:查看外壳变量的设定值。

例:echo $$ 显示当前进程PID2.常用系统调用函数常用系统调用函数、程序的说明、参数及定义如下:(1)fork()函数功能:创建一个新进程函数格式:int fork()其中返回int取值意义如下:小于0:创建失败0: 创建成功,在子进程中返回0值大于0: 创建成功,在父进程中返回子进程id值-1:创建失败(2)wait()函数功能:父进程等待子进程终止,以便对子进程进行善后处理。

函数格式:int wait(int *statloc)参数定义:statloc 指出子进程终止状态码的位置。

若不关心子进程的终止状态,可传递一个空指针。

返回值:正常返回时,为终止子进程的PID;错误返回时为-1;其他为0。

实验2 进程控制

实验2 进程控制

实验二进程控制1.学时:2,课外学时8。

2.实验类型:设计性实验3.实验目的:(1)加深对进程概念的理解,明确进程与程序的区别。

(2)进一步认识并发执行的实质。

(3)分析进程争用资源的现象,学习解决进程互斥的方法。

(4)熟悉linux下gcc工具的使用4.实验内容:题目一 4个fork。

写出以下程序输出结果,并画出进程家族树(必须编号)。

#include <unistd.h>int main(void){fork();fork();fork();fork();putchar('A');}题目二父进程不创建孙子进程。

如果父进程需要创建3子进程,但不想创建孙子进程。

编写程序,并画出进程家族树。

题目三父进程创建4个进程。

如果父进程需要创建4个进程,画出所有可能进程家族树。

题目四进程创建。

编写一段程序,使用系统调用fork()创建两个子进程。

当此程序运行时,在系统中有一个父进程和两个子进程活动。

让每一个进程在屏幕上显示一个字符:父进程显示“a“;两个子进程分别显示字符”b“和字符“c”。

试观察记录屏幕上的显示结果,并分析原因。

题目五子进程利用exec函数执行特定操作。

用fork( )创建一个进程,再调用exec( )用新的程序替换该子进程的内容;利用wait( )来控制进程执行顺序。

5.实验指导一)所涉及的系统调用1.fork( )创建一个新进程。

系统调用格式:pid=fork( )参数定义:fork( )返回值意义如下:0:在子进程中,pid变量保存的fork( )返回值为0,表示当前进程是子进程。

>0:在父进程中,pid变量保存的fork( )返回值为子进程的id值(进程唯一标识符)。

-1:创建失败。

如果fork( )调用成功,它向父进程返回子进程的PID,并向子进程返回0,即fork( )被调用了一次,但返回了两次。

此时OS在内存中建立一个新进程,所建的新进程是调用fork( )父进程(parent process)的副本,称为子进程(child process)。

实验二Windows进程控制

实验二Windows进程控制

实验步骤与调试过程Windows所创建的每个进程都是以调用CreateProcess()API函数开始和以调用ExitProcess()或TerminateProcess()API函数终止。

1. 创建进程本实验显示了创建子进程的基本框架。

该程序只是再一次地启动自身,显示它的系统进程ID和它在进程列表中的位置。

步骤1:登录进入Windows XP Professional。

步骤2:在“开始”菜单中单击“程序”→“Microsoft Visual Studio 6.0”→“Microsoft Visual C++ 6.0”命令,进入Visual C++窗口。

步骤3:新建Win32 Console Application项目proccreate,再新建C++文件proccreate,将清单2-1复制到文件中。

清单2-1创建子进程清单程序见下面的主要算法和程序清单步骤4:编译,链接,运行。

步骤6:在工具栏单击“Execute Program”(执行程序) 按钮,或者按Ctrl + F5键,或者单击“Build”菜单中的“Execute proccreate.exe”命令,执行proccreate.exe 程序。

步骤7:按Ctrl + S键可暂停程序的执行,按Ctrl + Pause (Break) 键可终止程序的执行。

清单2-1展示的是一个简单的使用CreateProcess() API函数的例子。

首先形成简单的命令行,提供当前的EXE文件的指定文件名和代表生成克隆进程的号码。

大多数参数都可取缺省值,但是创建标志参数使用了:CREATE_NEW_CONSOLE, // 使用新的控制台标志,指示新进程分配它自己的控制台,这使得运行示例程序时,在任务栏上产生许多活动标记。

然后该克隆进程的创建方法关闭传递过来的句柄并返回main() 函数。

在关闭程序之前,每一进程的执行主线程暂停一下,以便让用户看到其中的至少一个窗口。

实验二 进程管理(linux)

实验二 进程管理(linux)

实验二进程管理(Linux)一、实验类型本实验为设计性实验。

二、实验目的与任务1)加深对进程概念的理解,明确进程和程序的区别。

2)进一步认识并发执行的实质三、预习要求1)进程的概念2)进程控制的概念及内容3)进程的并发执行4)熟悉互斥的概念5)用到的Linux函数有:fork(),lockf()等。

四、实验基本原理使用fork()系统调用来创建一个子进程,父进程和子进程并发执行,交替输出结果。

使用lockf()系统调用对临界区进行加锁操作,实现对共享资源的互斥使用。

五、实验仪器与设备(或工具软件)实验设备:计算机一台,软件环境要求: Linux操作系统和gcc编译器。

六、实验内容1)进程的创建编写一段程序,使用系统调用fork( ) 创建两个子程序。

当此程序运行时,在系统中有一个父进程和两个子进程活动。

让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。

运行程序10次,观察记录屏幕上的显示结果,并分析原因。

2)进程的控制修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,再观察程序执行时屏幕上出现的现象,并分析原因。

如果在程序中使用系统调用lockf()来给每一个进程加锁,可以实现进程间的互斥,观察并分析出现的现象。

(1)进程的创建参考程序如下:#include<stdio.h>main(){int p1,p2;while((p1=fork())==-1); //p父进程p1子进程1if(p1!=0){while(((p2=fork())==-1); //p父进程p2子进程2if(p2==0) putchar('b');else putchar('c');}else putchar('a');}运行结果:略cab bca bac分析:原因:Fork()函数有三个返回值:1.-1 执行不成功2.0 表示当前正在执行子进程3.其他数值表示当前正在执行父进程,值是子进程的进程标识符PID4.获取当前进程的标识符getpid()5.获取当前进程的父进程的标识符getppid()(2)进程的控制参考程序如下#include<stdio.h>main(){int p1,p2,i;while ((p1=fork())==-1); // 父进程p,子进程p1if(p1==0){for(i=0;i<500;i++)printf("child_p1_ %d\n",i);}else{while((p2=fork())==-1);//父进程p,子进程p2if(p2==0)for(i=0;i<500;i++)printf("chind_p2_ %d\n",i);else for(i=0;i<500;i++)printf("father_p_%d\n",i);}}运行结果:略分析:由于函数printf()输出和字符串之间不会被中断,因此字符串内部的字符顺序输出不变。

实验2 进程观察实验

实验2 进程观察实验

实验2 进程观察实验实验2进程观察实验实验二进程观察实验(二):进程的控制实验目的1、了解进程创建后对进程控制的系统调用,可实现对进程的有效控制2、掌握进程的睡眠、同步、撤消等进程控制方法实验内容1、通过相关命令,对进程的状态进行控制。

2、编写程序,采用fork()建立一个子进程。

采用有关的系统调用掌控进程的状态。

观测并分析多进程的继续执行次序及状态切换。

实验基础一、进程的掌控进程因创建而存在,因执行完成或异常原因而终止.在进程的生命周期中,进程在内存中有三种基本状态:就绪,执行,阻塞.进程状态的转换是通过进程控制原语来实现的。

linux操作系统提供更多了适当功能的系统调用及命令,去同时实现用户层的进程掌控。

二、相关的命令(1)呼吸选定时间继续执行格式:#sleepxx为选定呼吸的秒数。

(2)完结或中止进程kill注意:按下^z,暂停正在执行的process。

键入”bg”,将所暂停的process置入background中继续执行。

例:#gccfile1&^zstopped#bg(4)查阅正在background中继续执行的process继续执行格式:#jobs(5)结束或终止在background中的进程kill执行格式:#kill%n基准:kill%1中止在background中的第一个jobkill%2中止在background中的第二个job三、相关的系统调用在linux中fork()就是一个非常有价值的系统调用,但在linux中创建进程除了fork()之外,也需用与fork()协调采用的exec()。

1、exec()系列系统调用exec()系列,也可以用作崭新程序的运转。

fork()只是将父进程的用户级上下文拷贝到崭新进程中,而exec()系列可以将一个可以继续执行的二进制文件全面覆盖在崭新进程的用户级上下文的存储空间上,以修改崭新进程的用户级上下文。

exec()系列中的系统调用都顺利完成相同的功能,它们把一个崭新程序放入内存,去发生改变调用进程的继续执行代码,从而构成崭新进程。

进程控制(2)实验报告

进程控制(2)实验报告
#include<unistd.h> #include <stdio.h> main() { int p;
p=fork(); if (p>0)
printf("parent \n"); else{
printf("before execute exec\n "); execl("./hello","hello",(char *)0); printf("after execute exec\n "); } }
实验 3 进程控制(2)
实验目的 1、掌握 Linux 中如何加载子进程自己的程序; 2、掌握父进程通过创建子进程完成某项任务的方法; 3、掌握系统调用 exit()和_exit()调用的使用。
实验内容 1、设计一程序,父进程创建一子进程,子进程的功能是输出“hello world!”,使 用 execl()加载子进程的程序。 实ቤተ መጻሕፍቲ ባይዱ步骤:
实验结果:
_exit(0)运行结果:
exit(0)运行结果:
printf("this is parent "); else{
printf("this is child first\n”); printf("this is child second ”); _exit(0); } }
注意:观察子进程的两个输出语句的执行结果。若_exit(0)换为 exit(0)结果会怎 样?(思考)
#include<unistd.h> #include <stdio.h> main() { printf("hello world!"); }

计算机操作系统实验-进程的控制

计算机操作系统实验-进程的控制

实验二:进程的控制1 .实验目的通过进程的创建、撤消和运行加深对进程概念和进程并发执行的理解,明确进程与程序之间的区别。

进程概念和程序概念最大的不同之处在于:(1)进程是动态的,而程序是静态的。

(2)进程有一定的生命期,而程序是指令的集合,本身无“运动”的含义。

没有建立进程的程序不能作为1个独立单位得到操作系统的认可。

(3)1个程序可以对应多个进程,但1个进程只能对应1个程序。

进程和程序的关系犹如演出和剧本的关系。

(4)进程和程序的组成不同。

从静态角度看,进程由程序、数据和进程控制块(PCB)三部分组成。

而程序是一组有序的指令集合。

2 .实验内容(1) 了解系统调用fork()、execvp()和wait()的功能和实现过程。

(2) 编写一段程序,使用系统调用fork()来创建两个子进程,并由父进程重复显示字符串“parent:”和自己的标识数,而子进程则重复显示字符串“child:”和自己的标识数。

(3) 编写一段程序,使用系统调用fork()来创建一个子进程。

子进程通过系统调用execvp()更换自己的执行代码,新的代码显示“new program.”。

而父进程则调用wait()等待子进程结束,并在子进程结束后显示子进程的标识符,然后正常结束。

3 .实验步骤(1)gedit创建进程1.c(2)使用gcc 1.c -o 1编译并./1运行程序1.c#include<stdio.h>#include<sys/types.h>#include<unistd.h>#include<sys/wait.h>void main(){int id;if (fork()==0){printf("child id is %d\n",getpid());}else if (fork()==0){printf("child2 id is %d\n",getpid());}else{id=wait(NULL);printf("parent id is %d\n",getpid());}}(3)运行并查看结果(4)gedit创建进程2.c使用gcc 2.c -o 2编译并./2运行程序2.c1 #include<stdio.h>2 #include<stdlib.h>3 #include<sys/types.h>4 #include<unistd.h>5 #include<sys/wait.h>6 int main()7 {8 pid_t pid;9 char *a[]={"ls","-l","/etc/passwd",0};10 int result;11 pid=fork();12 if(pid<0)13 {printf("fork error!");}14 else if(pid==0)15 {16 printf("new program!\n");17 execvp("ls",a);18 exit(0);19 }20 else21 {22 int e=waitpid(pid,&result,0);23 printf("child peocess PID:%d\n",e);24 exit(0);25 }26 }(5)运行并查看结果4 .思考(1)系统调用fork()是如何创建进程的?1)申请空白PCB 2)为新进程分配资源3)初始化进程控制块(初始化标识信息,初始化处理机状态信息,初始化处理机控制信息,)4)将新进程插入就绪队列(2)当首次将CPU 调度给子进程时,其入口在哪里?进程的进程控制块(PCB)结构中有指向其TTS(任务状态段)的指针,TTS里面存放着进程的入口。

国开电大 操作系统 实验2:进程管理实验报告

国开电大 操作系统 实验2:进程管理实验报告

一、实验题目:进程管理实验二、实验目的和要求:实验目的:(1)加深对进程概念的理解,尤其是进程的动态性、并发性。

(2)了解进程如何被创建和终止。

(3)学会查看进程的状态信息。

(4)学会使用进程管理命令。

(5)学会在后台运行进程。

实验要求:(1)理解有关进程的概念,能用ps命令列出系统中进程的有关信息,并进行分析。

(2)理解进程的创建及族系关系。

(3)能使用&,jobs,bg,at等命令控制进程的运行。

(4)了解终止进程的方法。

三、实验内容:1.使用ps命令查看系统中运行进程的信息。

2.利用系统调用实现进程的创建、终止、等待、睡眠等操作。

四、实验技术和方法:(说明:对本实验涉及的教材中的相关内容进行归纳总结,只需简要说明即可。

)加深对进城概念的理解,尤其是进程的动态性、并发性。

学会使用ps命令观察进程的状态,并分析进程族系关系;能使用& , jobs, bg, at 等命令控制进程的运行利用系统调用实现进程的创建、终止、等待、睡眠等操作。

五、实验环境:(说明:列出本实验使用到的软件平台和工具,如Linux系统版本,shell类型,vi编辑工具等。

)在虚拟机中的Linux RedHat Linux 9六、实验步骤和结果:(说明:详细给出实验步骤和结果。

实验步骤不一定与《实验指南》中的完全一致。

对实验结果,除文字说明外,对一些关键结果,需要给出一些界面截图。

)1、输入ps 命令PS命令用来报告系统当前的进程状态。

2、输入ps –e命令可以显示系统中运行的所有进程,包括系统进程和用户进程。

3、输入ps –f命令可以得到进程详细信息。

4、输入ps –el 命令显示进程环境变量列出长表。

二、进程控制1、后台进程(1)$grep “注册用户名” /etc/passwd > /tmp/abc &(2)ps –p pid2、作业控制(1)进程休眠60秒 Sleep 60 &(2)进程休眠30秒 Sleep 30 &(3)查看进程状态 Jobs(4)把睡眠30秒的sleep命令放在前台执行 fg %2(5)当提示符出现后,再查看进程状态 jobs三、发送中断信号(1)后台运行sleep命令$sleep 120 &(2)查看sleep进程的状态$ps –p pid(3)终止sleep命令$kill -9 pid(4)再查看sleep进程的状态$ps –p pid四、减轻系统负载【at命令】让一个命令在指定的时间运行,并把结果输出在一个文件中例:at time>date>who><ctrl>dat 命令会把已执行命令的标准输出发送到用户的邮箱,用cat命令查看邮箱内容,显示结果。

实验 进程的描述与控制

实验  进程的描述与控制

实验2:进程的描述与控制2.4 实验内容与步骤Windows所创建的每个进程都是以调用CreateProcess()API函数开始和以调用ExitProcess()或TerminateProcess()函数终止。

1、创建进程本实验学习创建进程的基本框架。

该程序要求启动自身,显示它的系统进程ID和它在进程列表中的位置。

步骤1:登录进入Windows 2000 Professional。

步骤2:在“开始”菜单中单击“程序”、“Microsoft Visual Studio 6.0”“Microsoft Visual C++ 6.0”,进入Visual C++窗口。

步骤3:在工具栏单击“新建”按钮,编写代码保存为2-1.cpp。

参考类和函数:windows.h、iostream、stdio.h、GetModuleFileName()、ZeroMemory()、CreateProcess()、GetCurrentProcess()。

步骤4:单击“Build”菜单中的“Compile 2-1.cpp”命令,对2-1.cpp 进行编译。

步骤5:编译完成后,单击“Build”菜单中的“Build 2-1.exe”命令,建立2-1.exe可执行文件。

操作能否正常进行,如果不行,原因是什么?答: 操作能正常运行步骤6:在工具栏单击“Execute program”按钮,或者按Ctrl+F5键,或者单击“Build”菜单中的“Execute 2-1.exe”命令,执行2-1.exe 程序。

步骤7:按Ctrl+S键可暂停程序的执行,按Ctrl+Pause(Break)键可终止程序的执行。

程序运行时结果如下:创建了26个Clone ID为0-26的进程,最终结束后只留下第一个2. 正在运行的进程本实验用进程信息查询的API函数GetProcessVersion()与GetVersionEx(),确定运行进程的操作系统的版本号。

实操作业二:进程控制

实操作业二:进程控制

步骤一:进程的创建
仔细观察可以发现每次执行结果中进程的执行顺序是不定的,从进程并发执行来看,输出bca,acb等都有可能。

fork()创建进程所需的时间要多于输出一个字符的时间,因此在住进程创建进程2的同时,进程1就输出了“b”,而进程2和主进程的输出次序是随机性的,所以会出现上述结果。

步骤二:进程的控制
因为是在实验1的基础上进行的,所以,操作步骤与实验1差不多。

由于函数printf()输出的字符串之间不会被中断,因此字符串内部的字符顺序输出时不变。

但是,由于进程并发执行时调度顺序和父子进程的抢占处理机问题,输出字符串和先后顺序随着执行的不同而变化。

这与打印单字符的结果相同。

步骤三:管道通信
实现进程的管道通信。

使用系统调用pipe()建立一条管道线;两个子进程p1和p2分别向管道个写一句话:
Child 1 is sending a message!
Child 2 is sending a message!
而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。

实操作业二进程控制

实操作业二进程控制

实操作业二进程控制
进程控制是操作系统中的一个重要概念,它涉及到对进程的创建、执行、调度、终止等操作。

通过进程控制,操作系统可以实现对系统资源的
分配和管理,提高系统的效率和可靠性。

在本文中,将详细介绍进程的创建、执行、调度和终止的相关内容。

1.进程创建
进程的创建是指通过操作系统的创建进程的系统调用,创建一个新的
进程。

在进程创建过程中,操作系统需要进行以下几个步骤:
1.1分配内存空间:操作系统为新的进程分配内存空间,用于存储进
程的代码、数据和堆栈信息。

1.2初始化PCB:操作系统通过调用PCB(进程控制块)数据结构来
管理进程,所以在创建进程时,需要初始化进程的PCB,记录进程的状态、优先级、资源使用情况等信息。

1.3分配进程号:每个进程都有一个唯一的进程号(PID),用于系
统对进程的标识和管理,所以在创建进程时,操作系统需要为新的进程分
配一个进程号。

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

操作系统 实验2进程控制管理 实验报告
else
{
while((p2=fork( ))= = -1); /*创建子进程p2*/
if(p2= =0)
for(i=0;i<10;i++)
printf("son %d\n",i);
else
for(i=0;i<10;i++)
printf("parent %d\n",i);
}
}
5.退出后,用同样方法查看此文件的代码内容。
2)修改上述程序,每一个进程循环显示一句话。子进程显示'daughter…'及'son……',父进程显示'parent……',观察结果,分析原因。
实验用到的软件(:)
虚拟机VMWare/Virtual Box
fedora15
实验内容及关键步骤(代码)Q3(15分)
1.按照上一次实验的步骤,进入后需要切换到管理员,输入“su root”,输入密码之后,可以输入“ls”查看目录下的文件。附加:为了熟悉上一节实验课内容,我先创建了一个myleb2的文件夹,然后再在这个文件夹里创建一个子文件夹love,再在里面编译。
6.查看无问题后,输入“gcc –o test2 test2.c”,修改运行文件名,然后查看该文件夹下的所有文件,能看到“test2”运行文件。
7.运行“test2”文件,输入“./test2”,可查看运行结果为“daughter 0,daughter 1,daughter 2,daughter 3….. daughter 9”。
3.首先是读入文件内容,再次是看文件有没有指定程序运行,如果有则运行,如果没有则输出出错的信息。
实验中的问题及解决办法:

进程的控制_实验报告

进程的控制_实验报告

### 实验目的1. 理解操作系统进程控制的基本概念和原理。

2. 掌握进程的创建、同步、通信和终止等操作。

3. 熟悉Linux系统中的进程控制命令和系统调用。

4. 理解进程调度算法的基本原理和实现方法。

### 实验环境1. 操作系统:Linux2. 编程语言:C/C++3. 编译器:gcc4. 开发工具:vim### 实验内容本实验主要涉及以下内容:1. 进程的创建与终止2. 进程同步与通信3. 进程调度算法#### 1. 进程的创建与终止实验一:利用fork()创建进程```c#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main() {pid_t pid;pid = fork();if (pid < 0) {printf("fork() error\n");return 1;} else if (pid == 0) {printf("Child process, PID: %d\n", getpid()); printf("Child process is running...\n");sleep(2);printf("Child process is exiting...\n");return 0;} else {printf("Parent process, PID: %d\n", getpid()); printf("Parent process is running...\n");sleep(3);printf("Parent process is exiting...\n");wait(NULL);}return 0;}```实验二:利用exec()创建进程```c#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main() {pid_t pid;pid = fork();if (pid < 0) {printf("fork() error\n");return 1;} else if (pid == 0) {execlp("ls", "ls", "-l", (char )NULL); printf("execlp() error\n");return 1;} else {wait(NULL);}return 0;}```实验三:进程终止```c#include <stdio.h>#include <sys/types.h>#include <sys/wait.h>int main() {pid_t pid;pid = fork();if (pid < 0) {printf("fork() error\n");return 1;} else if (pid == 0) {printf("Child process, PID: %d\n", getpid()); sleep(2);printf("Child process is exiting...\n");exit(0);} else {wait(NULL);}return 0;}```#### 2. 进程同步与通信实验四:使用信号实现进程同步```c#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>#include <signal.h>int main() {pid_t pid;int status;int signalNo = 1;pid = fork();if (pid < 0) {printf("fork() error\n");return 1;} else if (pid == 0) {printf("Child process, PID: %d\n", getpid()); while (1) {pause();printf("Child process is running...\n"); }} else {printf("Parent process, PID: %d\n", getpid()); sleep(1);kill(pid, signalNo);wait(NULL);}return 0;}```实验五:使用管道实现进程通信```c#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main() {int pipefd[2];pid_t pid;char buffer[100];if (pipe(pipefd) == -1) {printf("pipe() error\n"); return 1;}pid = fork();if (pid < 0) {printf("fork() error\n"); return 1;} else if (pid == 0) {close(pipefd[0]);read(pipefd[1], buffer, sizeof(buffer));printf("Child process, PID: %d, Received: %s\n", getpid(), buffer);} else {close(pipefd[1]);write(pipefd[0], "Hello, Child!\n", 14);wait(NULL);}return 0;}```#### 3. 进程调度算法实验六:先来先服务(FCFS)调度算法```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/wait.h>#define NUM_PROCESSES 5#define TIME_QUANTUM 2typedef struct {int pid;int arrival_time;int burst_time;} Process;int main() {Process processes[NUM_PROCESSES] = {{1, 0, 5},{2, 1, 3},{3, 2, 4},{4, 3, 2},{5, 4, 1}};int i, j, time = 0, completed = 0;int wait_time[NUM_PROCESSES], turnaround_time[NUM_PROCESSES]; // Calculate waiting timefor (i = 0; i < NUM_PROCESSES; i++) {wait_time[i] = 0;}for (i = 0; i < NUM_PROCESSES; i++) {for (j = 0; j < i; j++) {wait_time[i] += processes[j].burst_time;}}// Calculate turnaround timefor (i = 0; i < NUM_PROCESSES; i++) {turnaround_time[i] = wait_time[i] + processes[i].burst_time;}// Calculate average waiting time and turnaround timeint total_wait_time = 0, total_turnaround_time = 0;for (i = 0; i < NUM_PROCESSES; i++) {total_wait_time += wait_time[i];total_turnaround_time += turnaround_time[i];}printf("Average waiting time: %.2f\n", (float)total_wait_time / NUM_PROCESSES);printf("Average turnaround time: %.2f\n",(float)total_turnaround_time / NUM_PROCESSES);return 0;}```实验七:时间片轮转调度算法```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/wait.h>#define NUM_PROCESSES 5#define TIME_QUANTUM 2typedef struct {int pid;int arrival_time;int burst_time;} Process;int main() {Process processes[NUM_PROCESSES] = {{1, 0, 5},{2, 1, 3},{3, 2, 4},{4, 3, 2},{5, 4, 1}};int i, j, time = 0, completed = 0;int wait_time[NUM_PROCESSES], turnaround_time[NUM_PROCESSES]; // Calculate waiting timefor (i = 0; i < NUM_PROCESSES; i++) {wait_time[i] = 0;}for (i = 0; i < NUM_PROCESSES; i++) {for (j = 0; j < i; j++) {wait_time[i] += processes[j].burst_time;}}// Calculate turnaround timefor (i = 0; i < NUM_PROCESSES; i++) {turnaround_time[i] = wait_time[i] + processes[i].burst_time;}// Calculate average waiting time and turnaround timeint total_wait_time = 0, total_turnaround_time = 0;for (i = 0; i < NUM_PROCESSES; i++) {total_wait_time += wait_time[i];total_turnaround_time += turnaround_time[i];}printf("Average waiting time: %.2f\n", (float)total_wait_time / NUM_PROCESSES);printf("Average turnaround time: %.2f\n",(float)total_turnaround_time / NUM_PROCESSES);return 0;}```### 实验总结通过本次实验,我对操作系统进程控制有了更深入的了解。

实验2:进程控制实验指导[xiwang]

实验2:进程控制实验指导[xiwang]

实验2:进程控制实验指导一、实验目的和要求1. 熟练使用Linux的C语言开发环境2. 学习并掌握Linux 编译工具gcc 的使用方法3. Linux操作系统下的熟悉并能够进行进程创建4. 掌握Linux操作系统下的并发进程间同步具体完成:二、实验指导1. 练习使用Linux 编辑器Vi,为输入源程序做准备。

利用Vi 编辑器完成例程的输入、编译、运行。

例程:#include <linux/unistd.h>int main( ){int i=getuid( ) ;printf(“Hello world! This is my uid: %d\\n”, i ) ;}2. vi编辑器常用命令(见下表)。

进入Vi编辑器:$vi 文件名↙3. 编译工具gccRed Hat Linux的编译器是gcc。

gcc软件包支持C、C++。

gcc的可执行文件在/usr/bin/gcc下,/lib和/usr/lib目录下是库文件。

/usr/include目录下是头文件。

gcc编译常用格式为:$gcc 源文件名↙(例如:$gcc aaa.c↙,将生成默认可执行文件a.out)或者 $gcc -o 目标文件名源文件名↙(例如:$gcc –o aaa aaa.c)4. 通过进程创建的应用实例,深刻理解进程创建的过程将以下例题输入运行,并分析运行结果#include <stdio.h>#include <sys/types.h>#include <unistd.h>int main(void){pid_t pid;int data=5;if((pid=fork())<0){printf("fork error\n");exit(0);}else if(pid==0){data--;printf("child\'s data is:%d\n",data);exit(0);}else{printf("parent\'s data is:%d\n",data);}exit(0);}5. 通过fork( )、wait( )、exit( )等实现进程创建、并发和同步。

实验二Windows2000进程控制

实验二Windows2000进程控制

实验二Windows2000进程控制Windows 2022年进程控制Windows 2022年进程控制一、背景知识Windows所创建的每个进程都从调用CreateProcess() API函数开始,该函数的任务是在对象管理器子系统内初始化进程对象。

每一进程都以调用ExitProcess() 或TerminateProcess() API函数终止。

通常应用程序的框架负责调用ExitProcess() 函数。

对于C++运行库来说,这一调用发生在应用程序的main() 函数返回之后。

Windows 2022年进程控制1、创建进程CreateProcess()调用的核心参数是可执行文件运行时的文件名及其命令行。

表2-1详细地列出了每个参数的类型和名称。

Windows 2022年进程控制表2-1 CreateProcess() 函数的参数参数名称__ lpApplivationName __ lpCommandLine __IITY___TES lpProcessAttributes使用目的全部或部分地指明包括可执行代码的EXE文件的文件名向可执行文件发送的参数返回进程句柄的安全属性。

主要指明这一句柄是否应该由其他子进程所继承__IITY___TES lpThreadAttributes BOOL bInheritHandle DWORDdwCreationFlage LPVOID lpEnvironment __ lpCurrentDirectory __INFO lpStartupInfo __SS___TION lpProcessInformation返回进程的主线程的句柄的安全属性一种标志,告诉系统允许新进程继承创建者进程的句柄特殊的创建标志(如CREATE___ED) 的位标记向新进程发送的一套环境变量;如为null值则发送调用者环境新进程的启动目录__INFO结构,包括新进程的输入和输出配置的详情调用的结果块;发送新应用程序的进程和主线程的句柄和IDWindows 2022年进程控制可以指定第一个参数,即应用程序的名称,其中包括相对于当前进程的当前目录的全路径或者利用搜索方法找到的路径;lpCommandLine 参数允许调用者向新应用程序发送数据;接下来的三个参数与进程和它的主线程以及返回的指向该对象的句柄的安全性有关。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验四进程控制
【实验目的】
1、掌握进程的概念,明确进程和程序的区别。

2、认识和了解并发执行的实质。

3、分析进程争用资源的现象,学习解决进程互斥的方法。

【实验内容】
1、进程的创建(必做题)
编写一段程序,使用系统调用fork( )创建两个子进程,在系统中有一个父进程和两个子进程活动。

让每个进程在屏幕上显示一个字符;父进程显示字符“a”,子进程分别显示字符“b”和“c”。

试观察记录屏幕上的显示结果,并分析原因。

<参考程序>
# include<stdio.h>
main()
{ int p1, p2;
while((p1=fork())= = -1);
if(p1= =0)
putchar(‘b’);
else
{ while((p2=fork())= =-1);
if(p2= =0)
putchar(‘c’);
else
putchar( ‘a’);
}
}
2、修改已编写的程序,将每个进程的输出由单个字符改为一句话,再观察程序执行时屏幕上出现的现象,并分析其原因。

(必做题)
<参考程序>
# include<stdio.h>
main()
{ int p1, p2, i;
while((p1=fork())= = -1);
if(p1= =0)
for(i=0;i<500;i++)
printf(“child%d\n”,i);
else
If(p2= =0)
for(i=0;i<500;i++)
printf(“son%d \n”,i);
else
for(i=0;i<500;i++)
printf(“daughter%d \n”,i);
}
}
3、编写程序创建进程树如图1和图2所示,在每个进程中显示当前进程识别码和父进程识别码。

(必做题)
【思考题】
1、系统是怎样创建进程的?
2、当首次调用新创建进程时,其入口在哪里?
3、当前运行的程序(主进程)的父进程是什么?
【实验报告】
1、列出调试通过程序的清单,分析运行结果。

2、给出必要的程序设计思路和方法(或列出流程图)。

3、回答思考题。

4、总结上机调试过程中所遇到的问题和解决方法及感想。

#include<stdio.h>
main()
{int p1,p2,p3;
while((p1=fork())==-1);
if(p1==0)
{
while((p2=fork())==-1);
if(p2==0)
{
父进程
图1 进程树
图2 进程树
if(p3==0)
{
printf("Process ID=%d,%c\n",getpid(), 'd');
}
else
printf("Process ID=%d,child Process ID=%d,%c\n",getpid(),p3, 'c'); }
else
printf("Process ID=%d,child Process ID=%d,%c\n",getpid(),p2, 'b');
}
else
printf("Process ID=%d,child Process ID=%d,%c\n",getpid(),p1,'a');
}
【实验相关资料】
一、进程概念
1.进程
UNIX中,进程既是一个独立拥有资源的基本单位,又是一个独立调度的基本单位。

一个进程实体由若干个区(段)组成,包括程序区、数据区、栈区、共享存储区等。

每个区又分为若干页,每个进程配置有唯一的进程控制块PCB,用于控制和管理进程。

PCB的数据结构如下:
⑴进程表项(Process Table Entry)。

包括一些最常用的核心数据,如: 进程标识符PID、用户标识符UID、进程状态、事件描述符、进程和U区在内存或外存的地址、软中断信号、计时域、进程的大小、偏置值nice、指向就绪队列中下一个PCB的指针P_Link、指向U区进程正文、数据及栈在内存区域的指针。

⑵ U区(U Area)。

用于存放进程表项的一些扩充信息。

每一个进程都有一个私用的U区,其中含有:进程表项指针、真正用户标识符u-ruid(read user ID)、有效用户标识符u-euid(effective user ID)、用户文件描述符表、计时器、内部I/O参数、限制字段、差错字段、返回值、信号处理数组。

由于UNIX系统采用段页式存储管理,为了把段的起始虚地址变换为段在系统中的物理地址,便于实现区的共享,所以还有:
⑶系统区表项。

以存放各个段在物理存储器中的位置等信息。

系统把一个进程的虚地址空间划分为若干个连续的逻辑区,有正文区、数据区、栈区等。

这些区是可被共享和保护的独立实体,多个进程可共享一个区。

为了对区进行管理,核心中设置一个系统区表,各表项中记录了以下有关描述活动区的信息:区的类型和大小、区的状态、区在物理存储器中的位置、引用计数、指向文件索引结点的指针。

⑷进程区表
系统为每个进程配置了一张进程区表。

表中,每一项记录一个区的起始虚地址及指向系统区表中对应的区表项。

核心通过查找进程区表和系统区表,便可将区的逻辑地址变换为物理地址。

2.进程映像
UNIX系统中,进程是进程映像的执行过程,也就是正在执行的进程实体。

它由三部分组成:
⑴用户级上、下文。

主要成分是用户程序;
⑵寄存器上、下文。

由CPU中的一些寄存器的内容组成,如PC,PSW,SP及通用寄存器等;
⑶系统级上、下文。

包括OS为管理进程所用的信息,有静态和动态之分。

3.进程树
在UNIX系统中,只有0进程是在系统引导时被创建的,在系统初启时由0进程创建1进程,以后0进程变成对换进程,1进程成为系统中的始祖进程。

UNIX利用fork( )为每个终端创建一个子进程为用户服务,如等待用户登录、执行SHELL命令解释程序等,每个终端进程又可利用fork( )来创建其子进程,从而形成一棵进程树。

可以说,系统中除0进程外的所有进程都是用fork( )创建的。

二、所涉及的中断调用
1、fork()
创建一个新的子进程。

其子进程会复制父进程的数据与堆栈空间,并继承父进程的用户代码、组代码、环境变量、已打开的文件代码、工作目录和资源限制。

系统调用格式:
int fork()
如果Fork成功则在父进程会返回新建立的子进程代码(PID),而在新建立的子进程中则返回0。

如果fork失败则直接返回-1。

2、wait()
等待子进程运行结束。

如果子进程没有完成,父进程一直等待。

wait( )将调用进程挂起,直至其子进程因暂停或终止而发来软中断信号为止。

如果在wait( )前已有子进程暂停或终止,则调用进程做适当处理后便返回。

系统调用格式:
int wait(status)
int *status;
其中,status是用户空间的地址。

它的低8位反映子进程状态,为0表示子进程正常结束,非0则表示出现了各种各样的问题;高8位则带回了exit( )的返回值。

exit( )返回值由系统给出。

核心对wait( )作以下处理:
(1)首先查找调用进程是否有子进程,若无,则返回出错码;
(2)若找到一处于“僵死状态”的子进程,则将子进程的执行时间加到父进程的执行时间上,并释放子进程的进程表项;
(3)若未找到处于“僵死状态”的子进程,则调用进程便在可被中断的优先级上睡眠,等待其子进程发来软中断信号时被唤醒。

3、exit()
终止进程的执行。

系统调用格式:
void exit(status)
int status;
其中,status是返回给父进程的一个整数,以备查考。

为了及时回收进程所占用的资源并减少父进程的干预,UNIX/LINUX利用exit( )来实现进程的自我终止,通常父进程在创建子进程时,应在进程的末尾安排一条exit( ),使子进程自我终止。

exit(0)表示进程正常终止,exit(1)表示进程运行有错,异常终止。

如果调用进程在执行exit( )时,其父进程正在等待它的终止,则父进程可立即得到其返回的整数。

核心须为exit( )完成以下操作:
(1)关闭软中断
(2)回收资源
(3)写记帐信息
(4)置进程为“僵死状态”。

相关文档
最新文档