实验三进程的创建和简单控制(学生教学提纲
- 格式:doc
- 大小:735.00 KB
- 文档页数:19
进程的创建系统课程设计一、课程目标知识目标:1. 理解进程的基本概念,掌握进程的创建、执行和消亡过程;2. 掌握操作系统中进程管理的基本原理,了解进程调度算法;3. 了解进程同步与互斥的概念,掌握进程间通信的基本方法。
技能目标:1. 能够运用所学知识,编写简单的进程创建程序;2. 学会使用操作系统的进程管理工具,进行进程监控和分析;3. 能够分析实际问题,设计进程同步机制,解决进程间通信问题。
情感态度价值观目标:1. 培养学生对计算机操作系统的兴趣,激发学习热情;2. 培养学生的团队协作意识,提高沟通与协作能力;3. 培养学生勇于探索、积极进取的精神风貌,树立正确的价值观。
课程性质:本课程为计算机科学与技术专业选修课,旨在帮助学生掌握操作系统中进程管理的基本原理和方法。
学生特点:学生具备一定的计算机基础,熟悉编程语言,但对操作系统的学习相对较浅。
教学要求:结合学生特点,本课程要求学生在理解基本原理的基础上,通过实践加深对进程管理的认识,培养实际操作能力。
教学过程中,注重引导学生主动探索,提高分析问题和解决问题的能力。
课程目标分解为具体学习成果,以便在教学设计和评估中实现有效监控。
二、教学内容1. 进程基本概念:进程的定义、进程与程序的关系、进程的属性;2. 进程的创建与执行:进程控制块(PCB)、进程状态转换、进程创建原语、进程终止原语;3. 进程调度:进程调度算法(FCFS、SJF、RR等)、调度策略的评价指标;4. 进程同步与互斥:同步互斥问题的产生、临界区、Peterson算法、信号量与管程;5. 进程间通信:消息传递、共享存储、管道通信;6. 死锁与饥饿:死锁的定义、预防与避免、饥饿问题及解决方案;7. 操作系统进程管理实例分析:Linux进程管理、Windows进程管理。
教学内容安排与进度:1. 第1周:进程基本概念、进程的创建与执行;2. 第2周:进程调度;3. 第3周:进程同步与互斥;4. 第4周:进程间通信;5. 第5周:死锁与饥饿;6. 第6周:操作系统进程管理实例分析。
进程的创建实验报告进程的创建实验报告引言:在计算机科学领域中,进程是一个非常重要的概念。
进程是计算机程序的执行实例,它具有独立的内存空间和执行环境。
进程的创建是操作系统中一个关键的操作,本实验旨在通过编写一个简单的程序来演示进程的创建过程。
实验目的:通过实验,我们的目标是深入理解进程的创建过程,并了解操作系统是如何管理进程的。
实验步骤:1. 引入必要的头文件:在开始编写代码之前,我们需要引入一些必要的头文件。
这些头文件包括<sys/types.h>、<sys/wait.h>和<unistd.h>。
这些头文件提供了创建进程所需的函数和数据类型。
2. 创建一个子进程:在主程序中,我们使用fork()函数来创建一个子进程。
fork()函数会在当前进程的基础上创建一个新的进程,这个新进程称为子进程。
子进程和父进程几乎完全相同,只有在返回值上有所区别。
如果fork()函数返回0,表示当前进程是子进程;如果返回一个正整数,表示当前进程是父进程。
3. 子进程的执行:在子进程中,我们可以编写任意的代码来执行特定的任务。
子进程可以使用exec()函数来执行其他程序,或者执行一系列的操作。
在本实验中,我们简单地输出一条信息,以展示子进程的执行过程。
4. 父进程的执行:在父进程中,我们可以编写代码来执行其他任务,或者等待子进程的结束。
在本实验中,我们使用wait()函数来等待子进程的结束。
wait()函数会暂停父进程的执行,直到子进程结束为止。
5. 编译和运行程序:在完成代码编写后,我们需要将程序编译成可执行文件,并运行它。
我们可以使用gcc编译器来编译程序,然后运行生成的可执行文件。
实验结果:在运行程序后,我们可以观察到以下结果:子进程开始执行。
父进程等待子进程结束。
子进程结束。
父进程继续执行。
结论:通过本实验,我们成功地演示了进程的创建过程。
我们了解了操作系统是如何管理进程,并且掌握了使用fork()函数来创建子进程的方法。
操作系统实验3进程的创建控制实验实验三的目标是通过实现一个进程控制程序,来加深我们对进程创建和控制机制的理解,并通过实践来熟悉和掌握相关的编程技巧。
在进行实验之前,我们需要先了解进程的一些基本概念和相关知识。
首先,进程的创建是通过操作系统中的系统调用来完成的。
在Linux系统中,常用的创建进程的系统调用有fork(和exec(。
fork(系统调用可以创建一个新的进程,该进程与调用fork(的进程几乎完全相同;而exec(系统调用则在新创建的进程中执行一个新的程序。
另外,进程的控制机制主要是通过进程的状态来实现的。
进程可以处于就绪状态、运行状态和阻塞状态。
就绪状态的进程可以被调度器选择后立即运行,而阻塞状态的进程则需要等待一些条件满足后才能被唤醒并变为就绪状态。
实验三的具体内容包括:1. 编写一个程序,通过调用fork(创建多个子进程。
子进程和父进程可以并行执行,共享程序的代码和数据段。
2. 子进程通过调用exec(系统调用执行不同的程序。
可以通过调用不同的exec(函数或者传入不同的参数来执行不同的程序。
3. 子进程执行的程序可能会产生不同的结果,比如输出不同的字符串或者产生不同的返回值。
我们可以通过wait(系统调用等待子进程退出,并获取子进程的返回值。
4. 父进程可以通过调用waitpid(系统调用来选择等待一些特定的子进程,以及获取特定子进程的返回值。
通过实验三的实践,我将更加深入地了解进程的创建和控制机制。
实验三的实验结果将让我熟悉和掌握相关的编程技巧,为我今后更加熟练地编写和控制进程打下坚实的基础。
总之,实验三是一个非常有意义的实验,将帮助我更加深入地理解进程的创建和控制机制,并通过实践获得相关的编程技巧。
这将对我今后的学习和实践有很大的帮助。
一、实验目的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.知识目标:学生能够理解进程、线程的基本概念,掌握进程创建、终止、阻塞、唤醒等基本操作,了解进程同步、互斥、死锁等现象及解决方法。
2.技能目标:学生能够使用操作系统提供的进程控制API进行进程创建、管理,能够运用进程同步、互斥机制解决实际问题。
3.情感态度价值观目标:培养学生对计算机科学和操作系统的兴趣,提高学生分析问题和解决问题的能力,培养学生的团队协作精神和自主学习能力。
二、教学内容本课程的教学内容主要包括:1.进程基本概念:进程、线程的定义,进程的属性、状态转换等。
2.进程控制:进程创建、终止、阻塞、唤醒等操作,进程优先级、时间片等调度策略。
3.进程同步:信号量、互斥量、条件变量等同步机制,死锁、饥饿等问题的解决方法。
4.进程通信:管道、消息队列、共享内存、信号量集等通信机制。
5.进程组和会话:进程组的概念,会话的控制,终端控制台的使用。
三、教学方法本课程采用多种教学方法相结合的方式,包括:1.讲授法:讲解基本概念、原理和方法,引导学生理解进程控制的核心内容。
2.讨论法:学生针对进程控制的相关问题进行讨论,提高学生的分析问题和解决问题的能力。
3.案例分析法:分析实际案例,让学生了解进程控制在操作系统中的应用和作用。
4.实验法:安排实验课,让学生动手实践,加深对进程控制的理解。
四、教学资源本课程的教学资源包括:1.教材:《操作系统原理与应用》等。
2.参考书:《现代操作系统》、《操作系统设计与实现》等。
3.多媒体资料:课件、教学视频等。
4.实验设备:计算机、网络设备等。
教学资源将根据教学内容和教学方法的需要进行选择和准备,以确保教学的顺利进行,提高学生的学习效果。
五、教学评估本课程的教学评估将采用多元化的评估方式,以全面、客观、公正地评价学生的学习成果。
具体包括:1.平时表现:通过课堂参与、提问、讨论等方式评估学生的学习态度和积极性。
进程创建系统课程设计一、教学目标本课程的教学目标是让学生掌握进程创建的基本原理和操作方法,理解进程的概念和特性,能够运用进程管理的相关知识解决实际问题。
具体分为以下三个方面:1.知识目标:学生需要掌握进程的定义、特性、状态转换以及进程控制块的概念;了解进程创建的原理和方法,理解进程调度和同步的基本概念。
2.技能目标:学生能够使用操作系统进行进程的创建和管理,掌握进程创建的命令和参数,了解如何查看进程信息和结束进程;能够运用进程管理的相关知识分析和解决实际问题。
3.情感态度价值观目标:通过学习进程创建的知识,培养学生对计算机科学和操作系统的兴趣,提高学生的问题解决能力和创新思维。
二、教学内容本课程的教学内容主要包括以下几个部分:1.进程的概念和特性:介绍进程的定义、特点和基本属性,让学生了解进程在操作系统中的重要性和作用。
2.进程的状态转换:讲解进程的不同状态以及状态之间的转换条件和方法,帮助学生理解进程的生命周期。
3.进程控制块:介绍进程控制块的概念和作用,讲解如何使用进程控制块来管理进程。
4.进程创建原理:讲解进程创建的原理和方法,包括系统调用、进程表、进程标识符等。
5.进程调度:介绍进程调度的概念和作用,讲解常用的进程调度算法,让学生了解操作系统如何管理进程的执行。
6.进程同步:讲解进程同步的概念和作用,介绍常用的同步机制和算法,帮助学生理解多进程之间的协作和竞争。
三、教学方法为了提高教学效果和学生的参与度,本课程将采用多种教学方法相结合的方式进行教学,包括:1.讲授法:通过讲解和演示,向学生传授进程创建的基本原理和操作方法。
2.讨论法:学生进行小组讨论和交流,引导学生主动思考和探索问题,提高学生的理解能力和问题解决能力。
3.案例分析法:通过分析实际案例,让学生了解进程管理在实际应用中的作用和效果。
4.实验法:安排实验课程,让学生亲手操作操作系统进行进程的创建和管理,增强学生的实践能力和操作技能。
(1)首先查找调用进程是否有子进程,若无,则返回出错码;(2)若找到一处于“僵死状态”的子进程,则将子进程的执行时间加到父进程的执行时间上,并释放子进程的进程表项;(3)若未找到处于“僵死状态”的子进程,则调用进程便在可被中断的优先级上睡眠,等待其子进程发来软中断信号时被唤醒。
4、exit()终止进程的执行。
系统调用格式:void exit(status)int status;其中,status 是返回给父进程的一个整数,以备查考。
为了及时回收进程所占用的资源并减少父进程的干预,LINUX/LINUX 利用exit( )来实现进程的自我终止,通常父进程在创建子进程时,应在进程的末尾安排一条exit( ),使子进程自我终止。
exit(0)表示进程正常终止,exit(1)表示进程运行有错,异常终止。
如果调用进程在执行exit( )时,其父进程正在等待它的终止,则父进程可立即得到其返回的整数。
核心须为exit( )完成以下操作:(1)关闭软中断(2)回收资源(3)写记帐信息(4)置进程为“僵死状态”参考程序#include<stdio.h>#include<unistd.h>main( ){in t 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);}}运行结果执行命令ls -l -color ,(按倒序)列出当前目录下所有文件和子目录;ls completed!分析原因程序在调用fork( )建立一个子进程后,马上调用wait( ),使父进程在子进程结束之前,一直处于睡眠状态。
进程创建实验报告第一篇:进程创建实验报告实验二进程的创建一、实验目的熟悉进程的创建过程,了解系统调用函数fork()和 execl()。
二、实验内容1、阅读实例代码fork1,并编辑、编译、运行,记录程序的运行结果,尝试给出合理的解释,查阅有关资料,掌握系统调用fork()的用法,返回值的意义。
2、阅读实例代码fork2,并编辑、编译、运行,记录程序的运行结果,尝试给出合理的解释,查阅有关资料,掌握在程序中运行一个操作系统命令和运行一个程序的方法。
3、修改fork2,使之能把运行的命令和程序作为参数传给fork2。
三、设计思想1、程序框架pid =-1 pid = 0 pid > 02、用到的文件系统调用函数 fork()和 execl()四、调试过程1、测试数据设计(1)fork1 命名程序1:编写程序1:编译程序1:运行程序1:(2)fork2 编写程序2:运行程序2:(3)修改fork2 编写修改程序2:修改后的运行结果:2、测试结果分析(1)对于程序1:因为系统调用fork()函数是一次调用两次返回值,而且先生成子进程还是父进程是不确定的,所以第一次执行生成子进程的时候返回的pid = 0,判断pid!=-1,所以输出了I’m the child.I’m the parent.第二次,执行父进程的时候,返回的是子进程的进程号pid > 0,即pid的值仍然不为-1,所以又输出了一次I’m the child.I’m the parent。
(2)对于程序2:第一次调用fork()函数时,由于执行的是子进程还是父进程是随机的,所以第一次对父进程返回的是子进程的进程号(大于0),即pid > 0,所以输出I’m the parent.Program end.当第二次执行子进程时返回值是0,即pid = 0,所以输出I’m the child.并调用了execl()函数,查看了指定路径中的文件。
进程创建课程设计一、教学目标本课程的学习目标包括知识目标、技能目标和情感态度价值观目标。
知识目标要求学生掌握进程创建的基本概念和原理,了解不同操作系统中进程创建的机制和过程。
技能目标要求学生能够运用进程创建的知识解决实际问题,如设计和实现一个简单的进程创建程序。
情感态度价值观目标要求学生培养对计算机科学和编程的兴趣和热情,提高学生的问题解决能力和创新意识。
通过本课程的学习,学生将能够理解进程创建的重要性,掌握进程创建的基本原理和方法,培养学生的编程能力和创新思维。
同时,学生将能够将进程创建的知识应用到实际问题中,提高学生的问题解决能力。
此外,学生将培养对计算机科学和编程的兴趣和热情,提高学生的主观能动性和自我学习能力。
二、教学内容本课程的教学内容主要包括进程创建的基本概念和原理、不同操作系统中进程创建的机制和过程。
首先,将介绍进程创建的基本概念,如进程、线程、程序等,并解释它们之间的关系。
然后,将讲解不同操作系统中进程创建的机制和过程,包括常见的进程创建方法和技术。
在教学过程中,将结合具体的编程语言和开发环境,通过实例分析和实验操作,使学生能够深入理解进程创建的实现过程。
将介绍常用的进程创建接口和函数,如fork()、exec()等,并演示如何使用它们来实现进程创建。
同时,将结合实际应用场景,讲解进程创建在实际问题中的应用和意义。
三、教学方法为了激发学生的学习兴趣和主动性,将采用多样化的教学方法。
首先,将采用讲授法,向学生讲解进程创建的基本概念和原理,通过清晰的讲解和生动的例子,帮助学生理解和记忆。
同时,将鼓励学生参与讨论,提出问题和建议,促进学生的思考和交流。
其次,将采用案例分析法,通过分析具体的进程创建实例,使学生能够深入理解进程创建的实现过程和应用场景。
学生可以通过分析案例,发现问题并找到解决方案,提高学生的问题解决能力。
此外,将进行实验操作,让学生亲自动手编写进程创建的程序,并通过实验验证结果。
《操作系统原理》进程的创建与管理实验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中。
操作系统原理A实验报告学生姓名:陶浩学号:1708090122 班级:惠普测试171 实验名称:实验3 进程的创建与控制(2)实验指导教师:葛艳(二)进程的控制一、实验目的➢ 1. 掌握在子进程中使用execl()执行系统命令或调用已编译的其他可执行程序。
➢ 2. 掌握父进程通过创建子进程完成某项任务的方法。
➢ 3. 掌握系统调用exit()和_exit()的使用。
二、实验内容1.运行程序exit1.c(p32页),把运行结果截图。
再把_exit(0)换为exit(0),运行程序,把运行结果截图。
(1)分析修改前后运行结果出现的差异。
(2)分析exit(0)和_exit(0)的区别。
2.先编译运行下面的hello.c程序,然后在编译运行程序exec.c,把运行结果截图。
分析为什么子进程的最后两条语句(用红颜色标注)没有输出。
hello.c#include <stdio.h>main(){ printf(“In hello.c, ID=%d\n”,getpid());printf(“hello\n");}exec.c#include <unistd.h>#include <stdio.h>#include <errno.h>main(){ int p;p=fork();if (p>0){ printf("In the parent\n");wait(0);}else{ printf(“In child, ID=%d\n”,getpid());printf("before execute execl\n");execl("./hello","hello",NULL);perror("execl failed to run hello");printf("after execute execl\n");}}三、实验步骤及运行结果分析1.运行程序exit1.c(p32页),把运行结果截图。
实验三进程控制与描述➢背景知识➢实验目的➢工具/准备工作➢实验内容与步骤背景知识Windows的任务管理器提供了用户计算机上正在运行的程序和进程的相关信息,也显示了最常用的度量进程性能的单位。
使用任务管理器,可以打开监视计算机性能的关键指示器,快速查看正在运行的程序的状态,或者终止已停止响应的程序。
也可以使用多个参数评估正在运行的进程的活动,以及查看CPU和内存使用情况的图形和数据。
其中:1)“应用程序”选项卡显示正在运行程序的状态,用户能够结束、切换或者启动程序。
2)“进程”选项卡显示正在运行的进程信息。
例如,可以显示关于CPU和内存使用情况、页面错误、句柄计数以及许多其他参数的信息。
3)“性能”选项卡显示计算机动态性能,包括CPU和内存使用情况的图表,正在运行的句柄、线程和进程的总数,物理、核心和认可的内存总数(KB)等。
实验目的通过在Windows任务管理器中对程序进程进行响应的管理操作,熟悉操作系统进程管理的概念,学习观察操作系统运行的动态性能。
工具/准备工作在开始本实验之前,请回顾教科书的相关内容。
需要准备一台运行Windows操作系统的计算机。
实验内容与步骤1.使用任务管理器终止进程2.显示其他进程计数器3.更改正在运行的程序的优先级启动并进入Windows环境,单击Ctrl+Alt+Del键,或者右键单击任务栏,在快捷菜单中单击“任务管理器”命令,打开“任务管理器”窗口,如图6所示。
图6Windows的任务管理器在本次实验中,你使用的操作系统版本是:Windows 7 旗舰版当前机器中由你打开,正在运行的应用程序有:1)Word文档2)QQ3)控制面板4)U盘Windows“任务管理器”的窗口由__6__个选项卡组成,分别是:1)应用程序2)进程3)服务4)性能5)联网6)用户当前“进程”选项卡显示的栏目分别是(可移动窗口下方的游标/箭头,或使窗口最大化进行观察):1) 映像名称 2) 用户名3) CPU 4)内存(专用工作集)5)描述1.使用任务管理器终止进程步骤1:单击“进程”选项卡,一共显示了___55___个进程。
实验三创建进程实验目的: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.认识进程的并发执行,了解进程族之间各种标识及其存在的关系;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命令显示系统中进程层次结构。
a)pstree指令用ASCII字符显示树状结构,清楚地表达进程间的相互关系。
b)语法格式pstree [-acGhlnpuUV][-H <程序识别码>][<程序识别码>/<用户名称>](二)Linux简单进程编程1.理解系统调用fork()的使用。
a)fork()会产生一个与父程序相同的子程序,唯一不同之处在于其进程号,如图1所示。
图 1 系统调用fork()b)编辑下面的程序,要求实现父进程产生两个子进程,父进程显示字符“a”、两个子进程,分别显示字符“b”、“c”,如图2所示。
#include<stdio.h>main( ){int p1,p2;while ((p1=fork())==-1); /*父进程创建第一个进程,直到成功*/if(p1==0) /*0返回给子进程1*/{putchar('b');/*P1的处理过程*/}else ①{ /*正数返回给父进程(子进程号)*/while ((p2=fork())==-1); /*父进程创建第二个进程,直到成功*/if(p2==0) /*0返回给子进程2*/{putchar('c');/*P2的处理过程*/}else{putchar('a');/*P2创建完成后,父进程的处理过程*/}}}图2系统调用fork()的使用示例一思考:i.编译连接通过后,多次运行程序,观察进程并发执行结果,并分析原因。
原因:当程序并发执行时,系统处于一个复杂的动态组合状态,各程序执行的相对速度不确定,这使得这些程序多次并发执行得到的结果不同,调度、执行的顺序由系统决定。
ii.删除语句①,观察输出的内容,体会fork的使用。
提示:编译和运行该程序,分析结果出现两种输出的原因。
删除语句①后:思考的问题:1.运行命令为什么是“./command”?将源文件保存为以.c为后缀名的文件,开始进行编译$gcc -o XXX XXX.c 编译成功完成后,在当前路径下,生成一个名为XXX的文件然后执行$./XXX程序得以运行2.. 和.. 什么含义?.表示当前目录,..表示上级目录,即父目录3.shell 提示为什么不换行?因为在输出语句中没有/n换行符。
4.输出字母为什么和提示交错?b,a,shell,c四个进程并发执行,执行先后顺序由系统调度决定。
所以当shell调度在c进程前时,会出现输出字母和提示交错的现象。
5.管道什么含义?管道符,可以认为它是一根水管,连接输入端和输出端。
a | b其中,| 就是管道符,将输入端a命令产生的数据传给输出端的b命令来处理6../f1|pstree|grep f1什么含义?将./f1产生的数据传给pstree来处理,经过pstree处理后的数据再传给grep f1来处理在运行f1文件的进程的树结构中查找f1(?)7.6中组合命令为什么没有输出?(?)8.如果想保留6中的./f1的输出内容,该如何操作?进行重定向操作9../f1 运行结果为什么不一样?每种结果的产生原因。
有a,b,c三个并发进程,调度顺序由系统决定①bca②bac③abc10../f1|pstree|grep f1运行结果为什么不一样?截图中四种结果的产生原因。
由于并发进程的调度顺序是由系统决定的,并且pstree显示的是一刹那的进程,进程调度又是动态的。
四种结果:①无结果:可能三个进程调度已经结束或者还未开始调度②:父进程已经结束,两个子进程还在运行③:父进程开始运行,子进程还未开始调度④:两个子进程还在运行(?)注意:./f1 |pstree |grep f1命令之间有空格。
pstree 还可以加上参数,-up如:./f1 |pstree –up |grep f1提示:用pstree观察进程的父子关系,其中第二次不是错误,而是捕捉的时机,当时父进程已经结束,两个子进程还在运行。
扩展:修改代码,产生祖孙三代的进程。
说明:三个fe和bash都是进程,彼此间也会产生影响。
2.将上述的输出字符改为输出较长的字符串,如图3所示。
#include<stdio.h>int main( ){int p1,p2;while ((p1=fork())== -1); /*父进程创建第一个进程,直到成功*/if(p1==0) /*0返回给子进程1*/printf("boy\n"); /*P1的处理过程*/else{ /*正数返回给父进程(子进程号)*/while ((p2=fork())==-1); /*父进程创建第二个进程,直到成功*/if(p2 == 0) /*0返回给子进程2*/printf("daughter\n"); /*P2的处理过程*/elseprintf("parent\n"); /*P2创建完成后,父进程的处理过程*/ }}图3系统调用fork()的使用示例二思考:i.编译连接通过后,多次运行程序,观察进程并发执行结果:执行结果均为:ii.如果多次运行输出内容没有变化,请分析原因:函数fork( )用来创建一个新的进程,该进程几乎是当前进程的一个完全拷贝,所以多次运行输出内容没有变化iii.并改写原程序,延长每个进程的执行时间,再次观察运行情况。
延长执行时间后:输出的时间间隔变长3.(选作)将上述的输出字符改为多条输出语句,如图4所示。
#include<stdio.h>main( ){int p1,p2;int i;while ((p1=fork())==-1); /*父进程创建第一个进程,直到成功*/ if(p1==0) /*0返回给子进程1*/for( i =0; i < 1000; i++) /*P1的处理过程*/{putchar('b'); }else{ /*正数返回给父进程(子进程号)*/ while ((p2=fork())==-1); /*父进程创建第二个进程,直到成功*/if(p2==0) /*0返回给子进程2*/for( i =0; i < 1000; i++){putchar('c'); } /*P2的处理过程*/elsefor( i =0; i < 1000; i++){putchar('a'); } /*P2创建完成后,父进程的处理过程*/ }}图 4 系统调用fork()的使用示例三思考:i.编译连接通过后,多次运行程序,观察进程并发执行结果:ii.如果多次运行输出内容没有变化,请分析原因。
并改写原程序,延长每个进程的执行时间,再次观察运行情况。
iii.如果多次运行输出内容发生变化,并分析原因。
iv.将进程放在后台运行,用pstree观察进程的宗族关系。
v.系统创建一个新进程(使用系统调用fork)与让系统执行一个新程序(使用系统调用exec)有什么差异?4.理解系统调用wait()、getpid()和getppid()的使用。
程序代码如图5所示。
#include <stdio.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>int main(){char buf[100];pid_t cld_pid;int fd;if((fd=open("temp",O_CREAT|O_TRUNC|O_RDWR,S_IRWXU))==-1){printf("open error%d",errno);exit(1);}strcpy(buf,"This is parent process write\n");if((cld_pid=fork())==0){ /*这里是子进程执行的代码*/strcpy(buf,"This is child process write\n");printf("This is child process\n");sleep(1);printf("My PID (child) is%d\n",getpid()); /*打印出本进程的ID*/sleep(1);printf("My parent PID is %d\n",getppid()); /*打印出父进程的ID*/sleep(1);write(fd,buf,strlen(buf));close(fd);exit(0);}else{ /*这里是父进程执行的代码*/ wait(0); /*如果此处没有这一句会如何?*/printf("This is parent process\n");sleep(1);printf("My PID (parent) is %d\n",getpid()); /*打印出本进程的ID*/sleep(1);printf("My child PID is %d\n",cld_pid); /*打印出子进程的ID*/sleep(1);write(fd,buf,strlen(buf));close(fd);}return 0;}图5 系统调用wait()的使用思考:i.编译连接通过后,多次运行程序,观察进程并发执行结果:多次执行:ii.语句sleep(1);起什么作用?删除所有sleep(1);语句,并观察运行结果;让函数滞留1秒。