实验三 进程的创建和简单控制(学生.
操作系统实验报告进程管理
操作系统实验报告进程管理操作系统实验报告:进程管理引言操作系统是计算机系统中的核心软件,负责管理计算机的硬件资源和提供用户与计算机之间的接口。
进程管理是操作系统的重要功能之一,它负责对计算机中运行的各个进程进行管理和调度,以保证系统的高效运行。
本实验报告将介绍进程管理的基本概念、原理和实验结果。
一、进程管理的基本概念1. 进程与线程进程是计算机中正在运行的程序的实例,它拥有独立的内存空间和执行环境。
线程是进程中的一个执行单元,多个线程可以共享同一个进程的资源。
进程和线程是操作系统中最基本的执行单位。
2. 进程状态进程在运行过程中会经历不同的状态,常见的进程状态包括就绪、运行和阻塞。
就绪状态表示进程已经准备好执行,但还没有得到处理器的分配;运行状态表示进程正在执行;阻塞状态表示进程由于某些原因无法继续执行,需要等待某些事件的发生。
3. 进程调度进程调度是操作系统中的一个重要任务,它决定了哪个进程应该获得处理器的使用权。
常见的调度算法包括先来先服务(FCFS)、最短作业优先(SJF)和时间片轮转等。
二、进程管理的原理1. 进程控制块(PCB)PCB是操作系统中用于管理进程的数据结构,它包含了进程的各种属性和状态信息,如进程标识符、程序计数器、寄存器值等。
通过PCB,操作系统可以对进程进行管理和控制。
2. 进程创建与撤销进程的创建是指操作系统根据用户的请求创建一个新的进程。
进程的撤销是指操作系统根据某种条件或用户的请求终止一个正在运行的进程。
进程的创建和撤销是操作系统中的基本操作之一。
3. 进程同步与通信多个进程之间可能需要进行同步和通信,以实现数据共享和协作。
常见的进程同步与通信机制包括互斥锁、信号量和管道等。
三、实验结果与分析在本次实验中,我们使用了一个简单的进程管理模拟程序,模拟了进程的创建、撤销和调度过程。
通过该程序,我们可以观察到不同调度算法对系统性能的影响。
实验结果显示,先来先服务(FCFS)调度算法在一些情况下可能导致长作业等待时间过长,影响系统的响应速度。
操作系统实验3-进程控制
WORD wMajorReq=(WORD)(dwVerReq>16);
WORD wMinorReq=(WORD)(dwVerReq&0xffff);
::cout<<"Process ID:"<<dwIdThis<<",requires OS:"<<wMajorReq<<wMinorReq<<::endl;
{
//改变优先级
::SetPriorityClass(
::GetCurrentProcess(), //利用这一进程
HIGH_PRIORITY_CLASS); //改变为high
//报告给用户
::cout<<"Task Manager should indicate this "
"process is high priority."<<::endl;
//设置版本信息的数据结构,以便保存操作系统的版本信息
OSVERSIONINFOEX osvix;
::ZeroMemory(&osvix,sizeof(osvix));
osvix.dwOSVersionInfoSize=sizeof(osvix);
//提取版本信息和报告
::GetVersionEx(reinterpret_cast<LPOSVERSIONINFO>(&osvix));
Parent();
}
return 0;
}
分析:程序4-3.cpp说明了一个进程从“生”到“死”的整个一生,第一次执行时,它创建一个子进程,其行为如同“父亲”。在创建子进程之前,先创建一个互斥的内核对象,其行为对于子进程来说,如同一个“自杀弹”。当创建子进程时,就打开了互斥体并在其他线程中进行别的处理工作,同时等待着父进程使用ReleaseMutex()API发出“死亡”信号。然后用Sleep()API调用来模拟父进程处理其他工作,等完成时,指令子进程终止。
操作系统 实验三 进程同步
集美大学计算机工程学院实验报告课程名称:操作系统指导教师:王丰实验成绩:实验编号:实验三实验名称:进程同步班级:计算12姓名:学号:上机实践日期:2015.5上机实践时间:2学时一、实验目的1、掌握用Linux信号灯集机制实现两个进程间的同步问题。
2、共享函数库的创建二、实验环境Ubuntu-VMware、Linux三、实验内容⏹需要的信号灯: System V信号灯实现☐用于控制司机是否可以启动车辆的的信号灯 S1=0☐用于控制售票员是否可以开门的信号灯 S2=0System V信号灯实现说明□ System V的信号灯机制属于信号灯集的形式, 一次可以申请多个信号灯.□同样利用ftok()生成一个key: semkey=ftok(path,45);□利用key申请一个包含有两个信号灯的信号灯集, 获得该集的idsemid=semget(semkey,2,IPC_CREAT | 0666);□定义一个联合的数据类型union semun{int val;struct semid_ds *buf;ushort *array;};□利用semctl()函数对信号灯初始化,参数有:信号灯集的id: semid要初始化的信号灯的编号:sn要设定的初始值:valvoid seminit(int semid, int val,int sn){union semun arg;arg.val=val;semctl(semid,sn,SETVAL,arg);}利用初始化函数,初始化信号灯:seminit(semid,0,0);//用来司机启动汽车的同步seminit(semid,0,1);//用来售票员开门的同步控制□利用semop()函数, 对信号灯实现V操作:sembuf是一个在头部文件中的预定义结构、semid—信号灯集id, sn—要操作的信号灯编号void semdown(int semid,int sn){/* define P operating*/struct sembuf op;op.sem_num=sn;op.sem_op=-1;//P操作为-1op.sem_flg=0;semop(semid,&op,1);}2、Linux的静态和共享函数库·Linux生成目标代码: gcc -c 源程序文件名(将生成一个与源程序同名的.o目标代码文件。
操作系统实验三 时间片轮转法完成进程调度
实验三:时间片轮转法完成进程调度一、实验目的:(1)加深对进程的理解(2)理解进程控制块的结构(3)理解进程运行的并发性(4)掌握时间片轮转法进程调度算法实验内容:(1)建立进程控制块(2)设计三个链队列,分别表示运行队列、就绪队列和完成队列(3)用户输入进程标识符以及进程所需的时间,申请空间存放进程PCB信息。
(4)每一个时间片结束输出各进程的进程号,CPU时间(即已经占用的CPU时间),所需时间(即还需要的CPU时间),以及状态(即用W表示等待,R表示运行,F表示完成)实验程序:#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct node{char name[10];/*进程标识符*/int prio;/*进程优先数*/int round;/*进程时间轮转时间片*/int cputime; /*进程占用CPU时间*/int needtime; /*进程到完成还要的时间*/int count;/*计数器*/char state; /*进程的状态*/struct node *next; /*链指针*/}PCB;PCB *finish,*ready,*tail,*run; //队列指针int N,t; //进程数,时间片的大小void firstin(){run=ready;//就绪队列头指针赋值给运行头指针run->state='R'; //进程状态变为运行态ready=ready->next; //就绪队列头指针后移到下一进程}void prt1(char a)//输出标题函数{if(toupper(a)=='P')//优先级法printf("进程名占用CPU时间到完成还要的时间轮转时间片状态\n");} void prt2(char a,PCB *q)//进程PCB输出{if(toupper(a)=='P')//优先级法的输出printf("%4s %8d %12d %14d %8c\n",q->name,q->cputime,q->needtime,q->roun d,q->state);}void prt(char algo)//输出函数二、三、{PCB *p;prt1(algo);//输出标题if(run!=NULL)//如果运行指针不空prt2(algo,run);//输出当前正在运行的PCBp=ready;//输出就绪队列PCBwhile(p!=NULL){prt2(algo,p);p=p->next;}p=finish;//输出完成队列的PCBwhile(p!=NULL){prt2(algo,p);p=p->next;}getchar(); //按住任意键继续}void insert(PCB *q)//时间片轮转的插入算法{PCB *p1,*s,*r;s=q;//待插入的PCB指针p1=ready;//就绪队列头指针r=p1;//*r做pl的前驱指针while(p1!=NULL)if(p1->round<=s->round){r=p1;p1=p1->next;}if(r!=p1){r->next=s;s->next=p1;}else{s->next=p1;//否则插入在就绪队列的头ready=s;}}void create(char alg)//时间片轮转法创建链表进程PCB{PCB *p;int i,time;char na[10];ready=NULL;finish=NULL;run=NULL;printf("输入进程名及其需要运行的时间(中间以空格隔开):\n"); for(i=1;i<=N;i++){p=new PCB;scanf("%s %d",&na,&time);strcpy(p->name,na);p->cputime=0;p->needtime=time;p->state='W';//进程的状态p->round=0;if(ready!=NULL)insert(p);else{p->next=ready;ready=p;}}printf("*************时间片轮转法进程调度过程*************\n"); prt(alg);run=ready;ready=ready->next;run->state='R';}void timeslicecycle(char alg)//时间片轮转法{while(run!=NULL){run->cputime=run->cputime+t;//处理时间加trun->needtime=run->needtime-t;//完成需要时间减trun->round=run->round+t;//运行完将其变为完成态,插入完成队列if(run->needtime<=0)//当进程完成时{run->next=finish;finish=run;run->state='F';run=NULL;if(ready!=NULL)//就绪队列不空,将第一个进程投入进行firstin();}else{run->state='W';//将进程插入到就绪队列中等待轮转insert(run);//将就绪队列的第一个进程投入运行firstin();}prt(alg);}}void main()//主函数{char algo='P';//算法标记printf("输入进程的个数:");scanf("%d",&N);//输入进程数printf("定义时间片大小:");scanf("%d",&t);//输入时间片大小create(algo);//创建进程timeslicecycle(algo);//时间片轮转法调度}//main()四、实验结果:五、实验小结:时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法。
实验三-进程通讯实验报告
实验三进程通讯实验报告【姓名】【学号】【实验题目】进程通讯——消息队列与共享存储区【实验目的】(1)掌握进程间通讯的编程方法;(2)加深对进程并发执行的理解;(3)学习利用消息队列和共享存储区实现进程通信的方法。
【实验内容】设计一个多进程并发运行的程序,它由不同的进程完成下列工作:(1)接收键盘输入进程负责接收用户的键盘输入,并以适当的方式将由键盘获得的数据交给其它进程处理。
(2)显示进程负责全部数据显示任务,包括键盘输入数据的显示和提示信息的显示。
(3)分发数据进程将键盘输入的数据分为3类,即字母、数字和其它,并分别将字母写入文件letter.txt 中,数字写入文件number.txt中,除字母和数字外其它数据丢弃。
【实验要求】1、程序能以适当的方式提示用户输入数据;2、提示用户有数据被丢弃;3、全部的显示任务必须由显示进程完成;4、整个程序能够连续处理多组输入数据,直到用户输入“quit”字符串,整个程序结束;5、进一步要求:同时采用共享存储区和消息2种方法实现进程之间的通信,并比较这2种通信方法的利弊。
【实验方法】1、利用fork()函数创建2个子进程,用一个父进程和两个子进程完成上面的三个实验任务,用子进程1实现分发数据任务,子进程2实现接受键盘输入任务,父进程实现全部的显示任务。
2、同时通过共享存储区和消息队列两种进程通讯方式实现上面三个进程之间的同步和互斥。
3、利用while()循环、kill()函数和signal()函数实现连续多组数据输入。
【程序结构】·数据结构:消息队列、字符数组;·程序结构:顺序结构、if-else分支结构和while循环结构;·主要算法:无特别算法【实验结果】1、有代表性的执行结果:[stud13@localhost stud13]$ cc ipc.c[stud13@localhost stud13]$ ./a.outPlease input a line:∟operatingsystem01234-=,.Your message is:operatingsystem01234-=,.The characters deserted are:-=,.Please input a line:∟xushengju6651001!@#$%^&*()Your message is:xushengju6651001!@#$%^&*()The characters deserted are:!@#$%^&*()Please input a line:∟Hello123Your message is:Hello123Please input a line:∟quit[stud13@localhost stud13]$ cat letter.txtOperatingsystemxushengjuHello[stud13@localhost stud13]$ cat number.txt 012346651001123[stud13@localhost stud13]$2、结果分析及解释:在创建子进程1时,由于先返回子进程的ID号,msgrcv(msgid,&msg,BUFSIZE,0,0)一直都是非0值,故循环等待。
操作系统实验3进程的创建控制实验
操作系统实验3进程的创建控制实验实验三的目标是通过实现一个进程控制程序,来加深我们对进程创建和控制机制的理解,并通过实践来熟悉和掌握相关的编程技巧。
在进行实验之前,我们需要先了解进程的一些基本概念和相关知识。
首先,进程的创建是通过操作系统中的系统调用来完成的。
在Linux系统中,常用的创建进程的系统调用有fork(和exec(。
fork(系统调用可以创建一个新的进程,该进程与调用fork(的进程几乎完全相同;而exec(系统调用则在新创建的进程中执行一个新的程序。
另外,进程的控制机制主要是通过进程的状态来实现的。
进程可以处于就绪状态、运行状态和阻塞状态。
就绪状态的进程可以被调度器选择后立即运行,而阻塞状态的进程则需要等待一些条件满足后才能被唤醒并变为就绪状态。
实验三的具体内容包括:1. 编写一个程序,通过调用fork(创建多个子进程。
子进程和父进程可以并行执行,共享程序的代码和数据段。
2. 子进程通过调用exec(系统调用执行不同的程序。
可以通过调用不同的exec(函数或者传入不同的参数来执行不同的程序。
3. 子进程执行的程序可能会产生不同的结果,比如输出不同的字符串或者产生不同的返回值。
我们可以通过wait(系统调用等待子进程退出,并获取子进程的返回值。
4. 父进程可以通过调用waitpid(系统调用来选择等待一些特定的子进程,以及获取特定子进程的返回值。
通过实验三的实践,我将更加深入地了解进程的创建和控制机制。
实验三的实验结果将让我熟悉和掌握相关的编程技巧,为我今后更加熟练地编写和控制进程打下坚实的基础。
总之,实验三是一个非常有意义的实验,将帮助我更加深入地理解进程的创建和控制机制,并通过实践获得相关的编程技巧。
这将对我今后的学习和实践有很大的帮助。
进程管理实验报告_共10篇 .doc
★进程管理实验报告_共10篇范文一:_进程管理实验报告进程管理实验报告一、进程与线程1.实验目的:1.通过本实验学习Linux中创建进程的方法。
2.学习系统调用fork的使用方法。
3.学习系统调用exec族调用的使用方法。
2.实验准备1.进程的创建创建一个进程的系统调用很简单,只要调用fork函数就可以了。
#includepid_tfork();当一个进程调用了fork以后,系统会创建一个子进程,这个子进程和父进程是不同的地方只有它的进程ID和父进程ID,其他的都一样,就像父进程克隆(clone)自己一样,当然创建两个一模一样的进程是没有意义的,为了区分父进程和子进程,我们必须跟踪fork调用返回值。
当fork调用失败的时候(内存不足或者是用户的最大进程数已到)fork返回—1,否则fork的返回值有重要的作用。
对于父进程fork返回子进程ID,而对于fork 子进程返回0,我们就是根据这个返回值来区分父子进程的。
2.关于fork的说明使用该函数时,该函数被调用一次,但返回两次,两次返回的区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程ID。
将子进程ID返回给父进程的理由是:因为一个进程的子进程可以多于一个,所以没有一个函数可以是一个子进程获得其所有子进程的进程ID。
而fork函数使子进程得到的返回值是0的理由是:一个子进程只会有一个父进程,所以子进程总是可以调用函数getpid获得其父进程的进程ID。
3.系统调用exec族调用的说明父进程创建子进程后,子进程一般要执行不同的程序。
为了调用系统程序,我们可以使用系统调用exec族调用。
Exec族调用有以下五个函数:intexecl(constchar*path,constchar*arg,?);intexeclp(constchar*file,constchar*arg,?);intexecle(constchar*path,constchar*arg,?);intexecv(constchar*path,constchar*argv[]);intexecvp(constchar*file,constchar*argv[]);exec族调用可以执行给定程序。
进程管理实验报告分析(3篇)
第1篇一、实验背景进程管理是操作系统中的一个重要组成部分,它负责管理计算机系统中所有进程的创建、调度、同步、通信和终止等操作。
为了加深对进程管理的理解,我们进行了一系列实验,以下是对实验的分析和总结。
二、实验目的1. 加深对进程概念的理解,明确进程和程序的区别。
2. 进一步认识并发执行的实质。
3. 分析进程争用资源的现象,学习解决进程互斥的方法。
4. 了解Linux系统中进程通信的基本原理。
三、实验内容1. 使用系统调用fork()创建两个子进程,父进程和子进程分别显示不同的字符。
2. 修改程序,使每个进程循环显示一句话。
3. 使用signal()捕捉键盘中断信号,并通过kill()向子进程发送信号,实现进程的终止。
4. 分析利用软中断通信实现进程同步的机理。
四、实验结果与分析1. 实验一:父进程和子进程分别显示不同的字符在实验一中,我们使用fork()创建了一个父进程和两个子进程。
在父进程中,我们打印了字符'a',而在两个子进程中,我们分别打印了字符'b'和字符'c'。
实验结果显示,父进程和子进程的打印顺序是不确定的,这是因为进程的并发执行。
2. 实验二:每个进程循环显示一句话在实验二中,我们修改了程序,使每个进程循环显示一句话。
实验结果显示,父进程和子进程的打印顺序仍然是随机的。
这是因为并发执行的进程可能会同时占用CPU,导致打印顺序的不确定性。
3. 实验三:使用signal()捕捉键盘中断信号,并通过kill()向子进程发送信号在实验三中,我们使用signal()捕捉键盘中断信号(按c键),然后通过kill()向两个子进程发送信号,实现进程的终止。
实验结果显示,当按下c键时,两个子进程被终止,而父进程继续执行。
这表明signal()和kill()在进程控制方面具有重要作用。
4. 实验四:分析利用软中断通信实现进程同步的机理在实验四中,我们分析了利用软中断通信实现进程同步的机理。
进程控制与进程通信程序实验报告
进程控制与进程通信程序实验报告一、引言进程是计算机系统中最基本的概念之一,是操作系统中最小的资源管理单位。
进程控制与进程通信是操作系统中重要的内容,涉及到进程的创建、调度和终止,以及进程间的信息传递和同步管理。
本实验旨在通过编写进程控制与进程通信程序,加深对操作系统中进程管理和通信机制的理解。
二、实验目的1. 理解进程的概念和特点,掌握进程的创建、调度和终止方法。
2. 掌握进程通信的基本原理和方法,包括共享内存、管道、消息队列和信号量等。
3. 能够编写简单的进程控制和进程通信程序。
三、实验内容1. 进程控制实验:编写一个程序,实现进程的创建、调度和终止。
通过调用系统调用函数,创建多个子进程,并通过进程控制函数实现父子进程的协作与同步。
2. 进程通信实验:编写一个程序,实现进程间的信息传递和同步管理。
通过共享内存、管道、消息队列或信号量等机制,实现不同进程之间的数据交换和共享。
四、实验步骤1. 进程控制实验:(1)创建父进程和子进程:使用fork()函数创建子进程,并通过判断返回值来区分父子进程。
(2)调度子进程:使用wait()函数等待子进程的结束,以实现父子进程的同步。
(3)终止子进程:使用exit()函数终止子进程的运行。
2. 进程通信实验:(1)共享内存:使用shmget()函数创建共享内存段,使用shmat()函数映射共享内存到进程的地址空间,实现共享数据的读写。
(2)管道:使用pipe()函数创建管道,使用fork()函数创建子进程,通过读写管道实现进程间的数据传输。
(3)消息队列:使用msgget()函数创建消息队列,使用msgsnd()函数向消息队列发送消息,使用msgrcv()函数从消息队列接收消息,实现进程间的消息传递。
(4)信号量:使用semget()函数创建信号量,使用semop()函数对信号量进行P操作和V操作,实现进程间的同步和互斥。
五、实验结果通过实验,我们成功实现了进程的创建、调度和终止,以及进程间的信息传递和同步管理。
进程的调度实验报告(3篇)
第1篇一、实验目的通过本次实验,加深对操作系统进程调度原理的理解,掌握先来先服务(FCFS)、时间片轮转(RR)和动态优先级(DP)三种常见调度算法的实现,并能够分析这些算法的优缺点,提高程序设计能力。
二、实验环境- 编程语言:C语言- 操作系统:Linux- 编译器:GCC三、实验内容本实验主要实现以下内容:1. 定义进程控制块(PCB)结构体,包含进程名、到达时间、服务时间、优先级、状态等信息。
2. 实现三种调度算法:FCFS、RR和DP。
3. 创建一个进程队列,用于存储所有进程。
4. 实现调度函数,根据所选算法选择下一个执行的进程。
5. 模拟进程执行过程,打印进程执行状态和就绪队列。
四、实验步骤1. 定义PCB结构体:```ctypedef struct PCB {char processName[10];int arrivalTime;int serviceTime;int priority;int usedTime;int state; // 0: 等待,1: 运行,2: 完成} PCB;```2. 创建进程队列:```cPCB processes[MAX_PROCESSES]; // 假设最多有MAX_PROCESSES个进程int processCount = 0; // 实际进程数量```3. 实现三种调度算法:(1)FCFS调度算法:```cvoid fcfsScheduling() {int i, j;for (i = 0; i < processCount; i++) {processes[i].state = 1; // 设置为运行状态printf("正在运行进程:%s\n", processes[i].processName); processes[i].usedTime++;if (processes[i].usedTime == processes[i].serviceTime) { processes[i].state = 2; // 设置为完成状态printf("进程:%s 完成\n", processes[i].processName); }for (j = i + 1; j < processCount; j++) {processes[j].arrivalTime--;}}}```(2)RR调度算法:```cvoid rrScheduling() {int i, j, quantum = 1; // 时间片for (i = 0; i < processCount; i++) {processes[i].state = 1; // 设置为运行状态printf("正在运行进程:%s\n", processes[i].processName); processes[i].usedTime++;processes[i].serviceTime--;if (processes[i].serviceTime <= 0) {processes[i].state = 2; // 设置为完成状态printf("进程:%s 完成\n", processes[i].processName); } else {processes[i].arrivalTime++;}for (j = i + 1; j < processCount; j++) {processes[j].arrivalTime--;}}}```(3)DP调度算法:```cvoid dpScheduling() {int i, j, minPriority = MAX_PRIORITY;int minIndex = -1;for (i = 0; i < processCount; i++) {if (processes[i].arrivalTime <= 0 && processes[i].priority < minPriority) {minPriority = processes[i].priority;minIndex = i;}}if (minIndex != -1) {processes[minIndex].state = 1; // 设置为运行状态printf("正在运行进程:%s\n", processes[minIndex].processName);processes[minIndex].usedTime++;processes[minIndex].priority--;processes[minIndex].serviceTime--;if (processes[minIndex].serviceTime <= 0) {processes[minIndex].state = 2; // 设置为完成状态printf("进程:%s 完成\n", processes[minIndex].processName); }}}```4. 模拟进程执行过程:```cvoid simulateProcess() {printf("请选择调度算法(1:FCFS,2:RR,3:DP):");int choice;scanf("%d", &choice);switch (choice) {case 1:fcfsScheduling();break;case 2:rrScheduling();break;case 3:dpScheduling();break;default:printf("无效的调度算法选择。
操作系统实验三实验报告
(一)进程创建
编写程序实现创建多个进程,并观察进程的执行情况。通过调用Windows API函数`CreateProcess`来创建新的进程。在创建进程时,设置不同的参数,如进程的优先级、命令行参数等,观察这些参数对进程执行的影响。
(二)进程控制
实现对进程的暂停、恢复和终止操作。使用`SuspendThread`和`ResumeThread`函数来暂停和恢复进程中的线程,使用`TerminateProcess`函数来终止进程。通过控制进程的执行状态,观察系统的资源使用情况和进程的响应。
(一)进程创建实验结果与分析
创建多个进程后,通过任务管理器观察到新创建的进程在系统中运行。不同的进程优先级设置对进程的CPU占用和响应时间产生了明显的影响。高优先级的进程能够更快地获得CPU资源,执行速度相对较快;而低优先级的进程则在CPU资源竞争中处于劣势,可能会出现短暂的卡顿或计一个多进程同步的程序,使用信号量、互斥量等同步机制来协调多个进程的执行。例如,实现一个生产者消费者问题,多个生产者进程和消费者进程通过共享缓冲区进行数据交换,使用同步机制来保证数据的一致性和正确性。
四、实验步骤
(一)进程创建实验步骤
1、打开Visual Studio 2019,创建一个新的C++控制台应用程序项目。
六、实验中遇到的问题及解决方法
(一)进程创建失败
在创建进程时,可能会由于参数设置不正确或系统资源不足等原因导致创建失败。通过仔细检查参数的设置,确保命令行参数、环境变量等的正确性,并释放不必要的系统资源,解决了创建失败的问题。
(二)线程控制异常
在暂停和恢复线程时,可能会出现线程状态不一致或死锁等异常情况。通过合理的线程同步和错误处理机制,避免了这些异常的发生。在代码中添加了对线程状态的判断和异常处理的代码,保证了线程控制的稳定性和可靠性。
进程管理实验报告
进程管理实验报告进程管理实验报告引言:进程管理是操作系统中的重要概念,它负责调度和控制计算机系统中的各个进程,确保它们能够有序地执行。
本实验旨在通过实际操作和观察,深入了解进程管理的原理和方法,并通过实验结果分析其影响因素和优化策略。
实验一:进程创建与终止在本实验中,我们首先进行了进程的创建和终止实验。
通过编写简单的程序,我们能够观察到进程的创建和终止过程,并了解到进程控制块(PCB)在其中的作用。
实验结果显示,当一个进程被创建时,操作系统会为其分配一个唯一的进程ID,并为其分配必要的资源,如内存空间、文件描述符等。
同时,操作系统还会为该进程创建一个PCB,用于存储该进程的相关信息,如进程状态、程序计数器等。
当我们手动终止一个进程时,操作系统会释放该进程所占用的资源,并将其PCB从系统中删除。
这样,其他进程便可以继续使用这些资源,提高系统的效率和资源利用率。
实验二:进程调度算法进程调度算法是决定进程执行顺序的重要因素。
在本实验中,我们通过模拟不同的进程调度算法,比较它们在不同场景下的表现和效果。
我们选择了三种常见的进程调度算法:先来先服务(FCFS)、最短作业优先(SJF)和轮转调度(RR)。
通过设置不同的进程执行时间和优先级,我们观察到不同调度算法对系统吞吐量和响应时间的影响。
实验结果显示,FCFS算法适用于执行时间较短的进程,能够保证公平性,但在执行时间较长的进程出现时,会导致等待时间过长,影响系统的响应速度。
SJF 算法在执行时间较长的进程时表现出色,但对于执行时间较短的进程,可能会导致饥饿现象。
RR算法能够在一定程度上平衡各个进程的执行时间,但对于执行时间过长的进程,仍然会影响系统的响应速度。
实验三:进程同步与互斥在多进程环境中,进程之间的同步和互斥是必不可少的。
在本实验中,我们通过模拟进程间的竞争和互斥关系,观察进程同步与互斥的实现方式和效果。
我们选择了信号量机制和互斥锁机制作为实现进程同步和互斥的方法。
操作系统实验进程调度
实验三进程调度一. 实验目的加深理解并模拟实现进程(作业)调度算法。
1)熟悉常用的进程调度算法, 如FCFS、SPF、FPF、高响应比优先、时间片轮转;2)结合所学的数据结构及编程知识, 选择三种进程调度算法予以实现。
二. 实验属性该实验为设计性实验。
三. 实验仪器设备及器材普通PC386以上微机四. 实验要求本实验要求2学时完成。
1)本实验要求完成如下任务:2)编程实现单处理机系统中的进程调度, 要求从FCFS、SPF、FPF、高响应比优先、时间片轮转算法中至少选择三个;3)最后编写主函数对所做工作进行测试。
实验前应复习实验中所涉及的理论知识和算法, 针对实验要求完成基本代码编写并完成预习报告、实验中认真调试所编代码并进行必要的测试、记录并分析实验结果。
实验后认真书写符合规范格式的实验报告(参见附录A), 并要求用正规的实验报告纸和封面装订整齐, 按时上交。
五: 实验具体设计此程序模拟了两种调度算法, FCFS和SPF, 首先FCFS就是按照进程的创建顺序依次顺序进行, 流程图为:进程顺序执行SPF:每次都进行循环, 选出在该时间刻运行时间最短的进程优先执行。
1.程序代码具体详解:2.创建一结构体作为进程控制器typedef struct PCB{int ID;char state;int arrivetime;int starttime;int finishtime;int servicetime;struct PCB *next;}pcb;定义全局变量作为计时器int time;//计时器创建进程链表:从txt文件中读取数据, 构造一条不含头结点的单链表void Create_process(){ifstream inFile;inFile.open("test.txt");inFile>>n;inFile.get();int i=0;for (;i<n;i++){p=(pcb *)malloc(sizeof(pcb));inFile>>p->ID;inFile>>p->arrivetime;inFile>>p->servicetime;p->starttime=0;p->finishtime=0;p->state='F';p->next=NULL;if(head==NULL){head=p;q=p;time=p->arrivetime;}if(p->arrivetime < time)time=p->arrivetime;q->next=p;q=p;}若执行FCFS算法, 按顺序遍历链表void fcfs1(){int i;p=head;for(i=0;i<n;i++){if(p->state=='F')q=p;run_fcfs1(q);}p=p->next;}}void run_fcfs1(pcb *p1){time = p1->arrivetime > time? p1->arrivetime:time;p1->starttime=time;printf("\n现在时间: %d,开始运行作业%d\n",time,p1->ID);time+=p1->servicetime;p1->state='T';p1->finishtime=time;printf("ID号到达时间开始运行时间服务时间完成时间\n");printf("%d%10d%12d%12d%12d\n",p1->ID,p1->arrivetime,p1->starttime,p1->servicetime,p 1->finishtime);}若执行SPF算法, 每次都从链表头开始遍历链表, 找出arrivetime<=time并且运行时间最短的节点, 执行该节点进程, 最后再删除该节点。
操作系统实验报告三
操作系统实验报告三一、实验目的本次操作系统实验的目的在于深入了解操作系统的进程管理、内存管理和文件系统等核心功能,通过实际操作和观察,增强对操作系统原理的理解和掌握,提高解决实际问题的能力。
二、实验环境本次实验在 Windows 10 操作系统环境下进行,使用了 Visual Studio 2019 作为编程工具,并借助了相关的操作系统模拟软件和调试工具。
三、实验内容与步骤(一)进程管理实验1、创建多个进程使用 C++语言编写程序,通过调用系统函数创建多个进程。
观察每个进程的运行状态和资源占用情况。
2、进程同步与互斥设计一个生产者消费者问题的程序,使用信号量来实现进程之间的同步与互斥。
分析在不同并发情况下程序的执行结果,理解进程同步的重要性。
(二)内存管理实验1、内存分配与回收实现一个简单的内存分配算法,如首次适应算法、最佳适应算法或最坏适应算法。
模拟内存的分配和回收过程,观察内存的使用情况和碎片产生的情况。
2、虚拟内存管理了解 Windows 操作系统的虚拟内存机制,通过查看系统性能监视器观察虚拟内存的使用情况。
编写程序来模拟虚拟内存的页面置换算法,如先进先出(FIFO)算法、最近最少使用(LRU)算法等。
(三)文件系统实验1、文件操作使用 C++语言对文件进行创建、读写、删除等操作。
观察文件在磁盘上的存储方式和文件目录的结构。
2、文件系统性能测试对不同大小和类型的文件进行读写操作,测量文件系统的读写性能。
分析影响文件系统性能的因素,如磁盘碎片、缓存机制等。
四、实验结果与分析(一)进程管理实验结果1、创建多个进程在创建多个进程的实验中,通过任务管理器可以观察到每个进程都有独立的进程 ID、CPU 使用率、内存占用等信息。
多个进程可以并发执行,提高了系统的资源利用率。
2、进程同步与互斥在生产者消费者问题的实验中,当使用正确的信号量机制时,生产者和消费者能够协调工作,不会出现数据不一致或死锁的情况。
操作系统实验---进程的创建与控制
实验报告实验题目姓名:学号:课程名称:操作系统实验所在学院:信息科学与工程学院专业班级:计算机任课教师:核心为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.创建进程(1)打开实验环境,启动操作系统。
(2)使用编程语言(如C语言)编写一个简单的程序,该程序将创建一个新的进程。
(3)编译并运行程序,观察和记录进程的创建过程。
3.进程切换(1)编写一个程序,该程序将在两个进程之间进行切换。
(2)运行程序,观察和记录进程切换的过程和效果。
4.进程同步(1)使用信号量或其他同步机制实现两个进程的同步。
(2)运行程序,观察和记录进程同步的过程和效果。
5.进程终止(1)编写一个程序,该程序将终止一个指定的进程。
(2)运行程序,观察和记录进程终止的过程和效果。
6.实验总结与报告编写(1)总结实验过程和结果,梳理实验中的问题和解决方法。
(2)编写实验报告,包括实验目的、原理、步骤、结果分析等。
四、实验结果与分析通过本次实验,我们成功地创建了一个新的进程,并实现了进程之间的切换、同步和终止。
在实验过程中,我们深入理解了进程控制的概念、原理和实现方式,掌握了进程控制的技巧和方法。
同时,我们也遇到了一些问题,如进程创建失败、进程切换不成功等,但通过仔细分析问题原因并采取相应的解决方法,最终成功解决了这些问题。
通过本次实验,我们不仅学到了专业知识,也提高了解决实际问题的能力。
五、实验结论与建议本次实验让我们更加深入地理解了进程控制的相关知识,并掌握了进程控制的基本操作方法。
进程控制 实验报告
进程控制实验报告进程控制实验报告一、引言进程控制是操作系统中的重要概念,它涉及到进程的创建、调度、终止等方面。
本篇实验报告将介绍我们在进程控制实验中所进行的工作和实验结果。
二、实验目的本次实验的目的是通过编写程序,了解进程的创建、调度和终止过程,并掌握相关的系统调用和操作。
三、实验环境我们使用的实验环境是Linux操作系统,并使用C语言编写程序。
四、实验步骤1. 进程创建在实验中,我们编写了一个简单的程序,用于创建新的进程。
通过调用系统调用fork(),我们可以在父进程中创建一个子进程。
子进程是父进程的副本,它们共享一些资源,但有各自独立的执行空间。
2. 进程调度在实验中,我们使用了系统调用exec()来进行进程调度。
通过调用exec(),我们可以在一个进程中执行另一个可执行文件。
这样,原来的进程将被替换为新的进程,并开始执行新的程序。
3. 进程终止在实验中,我们使用了系统调用exit()来终止一个进程。
当一个进程执行完毕或者遇到错误时,可以调用exit()来结束自己的执行。
同时,exit()函数还可以传递一个整数值作为进程的返回值,供其他进程获取。
五、实验结果通过实验,我们成功地创建了多个进程,并进行了调度和终止操作。
我们观察到,创建的子进程在父进程的基础上执行,并且具有独立的执行空间。
在调度过程中,我们能够看到进程的切换和执行结果的输出。
在终止过程中,我们成功地结束了进程的执行,并获取了进程的返回值。
六、实验总结通过本次实验,我们深入了解了进程控制的相关概念和操作。
我们通过编写程序,实际操作了进程的创建、调度和终止过程。
这些实验结果对于我们理解操作系统的工作原理和进程管理机制具有重要意义。
七、实验感想本次实验让我们深刻认识到进程控制在操作系统中的重要性。
进程的创建、调度和终止是操作系统能够高效运行的基础。
通过实验,我们不仅掌握了相关的系统调用和操作,还加深了对操作系统原理的理解。
八、实验改进在实验中,我们可以进一步扩展功能,例如实现进程间的通信和同步机制。
进程的控制_实验报告
### 实验目的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;}```### 实验总结通过本次实验,我对操作系统进程控制有了更深入的了解。
3-实验三 进程管理
实验3 进程管理一、实验目的1.加深对进程概念的理解,尤其是进程的动态性,并发性;2.了解父进程和子进程之间的关系;3.查看进程管理命令;二、实验内容1.练习进程管理有关命令ps (察看进程状态)ps命令提供了当前运行进程的快照,示例如下:$ psPID TTY TIME CMD3884 pts/1 00:00:00 bash3955 pts/2 00:00:00 more3956 pts/3 00:00:00 sqlplus其中,PID是进程的标识号;TTY是进程所属的终端控制台;TIME列是进程所使用的总的CPU时间;CMD列列出正在执行的命令行。
ps命令还有其它参数,可得到更完整的进程列表,大家可以通过man试验一下。
2.练习在shell环境下编译执行程序(注意:①父子进程关系的程序在/mnt/share目录下,是sanple1.c②利用cp把源程序例子复制到自己的目录下;③或在vi 编辑器中重写名为sample1.c的c语言源程序;④用linux自带的编译器gcc编译程序,例如:gcc –o test test.c⑤编译后生成名为test.out的可执行文件;⑥最后执行分析结果;命令为:./test)注意:linux自带的编译程序gcc的语法是:gcc –o 目标程序名源程序名,例如:gcc –o sample1 sample1.c,然后利用命令:./sample 来执行。
如果仅用“gcc 源程序名”,将会把任何名字的源程序都编译成名为a.out的目标程序,这样新编译的程序会覆盖原来的程序,所以最好给每个源程序都起个新目标程序名。
3.进程的创建仿照例子自己编写一段程序,使用系统调用fork()创建两个子进程。
当此程序运行时,在系统中有一个父进程和两个子进程活动。
让每一个进程在屏幕上显示一个字符:父进程显示“a”,子进程分别显示字符“b”和“c”。
观察记录屏幕上的显示结果,并分析原因。
4.分析程序实验内容要在给出的例子程序基础上,根据要求进行修改,对执行结果进行分析。
北理操作系统实验三
操作系统课程设计实验报告实验名称:生产者消费者问题姓名/学号:一.实验目的1.学习掌握操作系统中进程之间的通信2.理解掌握使用信号量机制来多进程互斥访问共享内存区的控制3.学习进程的创建及控制,共享内存区的创建和删除,信号量的创建使用删除二.实验内容•一个大小为3的缓冲区,初始为空,每个缓冲区能存放一个长度若为10个字符的字符串。
•2个生产者–随机等待一段时间,往缓冲区添加数据,–若缓冲区已满,等待消费者取走数据后再添加–重复6次•3个消费者–随机等待一段时间,从缓冲区读取数据–若缓冲区为空,等待生产者添加数据后再读取–重复4次说明:•显示每次添加和读取数据的时间及缓冲区的状态•生产者和消费者用进程模拟,缓冲区用共享内存来实现三.实验环境VMware Fushion8:Windows和ubuntu14.10四.程序设计与实现1、Windows下:A:主要函数说明1.PROCESS_INFORMATION StartClone(int nCloneID)功能:创建一个克隆的进程并赋于其ID值,并返回进程和线程信息2.CreateProcess:创建进程3.CreateSemaphore():创建信号量4.CreateFileMapping():在当前运行的进程中创建文件映射对象,模拟共享内存区5.MapViewOfFile():在此文件映射基础上创建视图映射到当前应用程序的地址空间B:程序流程图(下图)C:实验结果:2、Linux下:A:主要函数说明1.void(p):申请缓冲区2.void(v):释放缓冲区3.shmget():用来获得共享内存区域的ID,如果不存在这个内存区,就创建这个共享内存区。
4.semget():返回信号量集的Id,如果不存在就创建这个信号量集B:程序流程图C:实验结果五. 实验收获与体会1、进一步熟悉了Windows 、Linux 中进程的创建与管理2、掌握了WINDOWS 和Linux 下进程之间的通信:Windows 主要在于句柄的获取并用于API 函数的调用,并利用文件映射创建共享缓冲区;Linux 主要使用信号量机制和相关API的调用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验三进程的创建和简单控制实验目的: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秒。