操作系统实验--进程控制

实验探讨了Linux环境下进程的创建与控制,通过fork()系统调用创建父子进程,并利用wait()确保进程顺序执行。实验结果显示多进程并发执行比单进程速度快,揭示了并发执行的优势。同时,给出了从单进程到多进程的转换示例,通过exec()函数实现并发运行多个程序,进一步比较了两种执行方式的时间差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验一 进程控制
一、实验目的:
加深对进程概念的理解,明确进程和程序的区别;掌握Linux操作系统的进程创建和终止操作,体会父进程和子进程的关系及进程状态的变化;进一步认识并发执行的实质,编写并发程序。
二、实验平台:
虚拟机:VMWare9以上
操作系统:Ubuntu12.04以上
编辑器:Gedit | Vim
编译器:Gcc
三、实验内容:
(1)编写一段程序,使用系统调用fork()创建两个子进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示“身份信息”:父进程显示“Parent process! PID=xxx1 PPID=xxx2”;子进程显示“Childx process! PID=xxx PPID=xxx”。多运行几次,观察记录屏幕上的显示结果,并分析原因。
wait()函数用来避免父进程在子进程终止之前终止。

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
 pid_t pid1;
 pid_t pid2;
 if((pid1=fork())<0){
 printf("fork1 failid\n");
 exit(0);}
 else if(pid1==0){//子进程pid1
 printf("Child1 process! PID=%d PPId=%d\n",getpid(),getppid());
 }
 else{
wait();
   if((pid2=fork())<0){
 printf("fork2 failid\n");
 exit(0);
 }
 else if(pid2==0){//子进程pid1
 printf("Child2 process! PID=%d PPId=%d\n",getpid(),getppid());
 }else{
     wait();
     printf("Parent process! PID=%d PPID=%d\n",getpid(),getppid());
     exit(0);}
 }

 return 0;
}

在这里插入图片描述

首先父进程创建子进程pid1等待pid1执行结束,然后创建子进程pid2,再等待pid2执行结束,最后父进程执行。

(2)fork()和exec()系列函数能同时运行多个程序,利用上述函数将下面单进程顺序执行的程序single.c改造成可并发执行3个进程的程序multi_process.c;并用time命令获取程序的执行时间,比较单进程和多进程运行时间,并分析原因。
//single.c
#include <stdio.h>
#define NUM 5
int main(void)
{
void print_msg(char *m);
print_msg("Good ");
print_msg(“Morning “);
print_msg(“007\n”); //将007替换为本人学号
return 0;
}
void print_msg(char *m)
{
int i;
for(i = 0; i<NUM; i++){
printf(”%s”,m);
fflush(stdout);
sleep(1);
}
}
编译运行方法:
#gcc single.c –o single
#time ./single

//pring.c

#include<stdio.h>
int main(int argc,char *argv[])
{
   char *m=(char *)argv[0];
	int i; 
	for(i = 0; i<5; i++){ 
	printf("%s",m); 
	fflush(stdout); 
	sleep(1);}
   return 0;
}
//multi_process.c
#include <stdio.h> 
#include<unistd.h>
#include<stdlib.h>
#define NUM 5 
int main(void) 
{ 
pid_t pid1;
//pid_t pid3;
pid_t pid2;

if((pid1=fork())<0){
 printf("fork1 faild\n");
     exit(0);
}else if(pid1==0){

execl("print","Good  ",NULL);
}
else{
 if((pid2=fork())<0){
printf("fork2 faild\n");
     exit(0);
}
else if(pid2==0){
execl("print","Morning  ",NULL);
}
else{
execl("print","201908064515  ",NULL);  //将007替换为本人学号
wait();
}
wait();
}
return 0; 
} 

在这里插入图片描述

首先观察单进程,跟多进程的数据结果,可以看到多进程运行速度比单进程快了3倍,主要是多进程创建了多个进程共同执行,各个进程执行不同的数据,相当于我有三个员工来做这个事,你只有一个人。

<think>好的,用户需要关于操作系统实验进程控制相关的教程或资料。我先看一下用户提供的引用内容。引用[1]提到了进程创建、状态控制、PCB概念以及链表的操作,引用[2]则是关于进程调度的实验任务。这说明用户可能在做涉及进程管理和调度的实验,需要具体的操作指导和理论支持。 首先,我应该整理进程控制的基础知识,比如进程创建的系统调用,例如fork()和exec(),这在Linux环境下很常见。然后需要解释进程控制块(PCB)的结构和作用,这部分可以结合数据结构中的链表管理,因为操作系统常用链表来组织PCB。接着,实验步骤可能需要编写代码创建进程,比如用C语言和系统调用,这部分需要示例代码,并解释每一步的作用。例如,在引用[1]中提到的创建进程和线程,可能需要展示fork()的使用。 用户可能还需要了解如何观察进程状态变化,比如使用ps命令,或者通过实验观察父子进程的执行顺序。引用[2]中提到去除wait后的结果分析,这可能涉及僵尸进程进程同步的问题,这部分需要解释wait()函数的作用以及未使用时的后果。 此外,用户可能需要参考资料和教程,可以推荐经典的操作系统教材,如《操作系统概念》和《现代操作系统》,以及在线资源如GeeksforGeeks和TutorialsPoint。实验报告模板和示例代码也会对用户有帮助,特别是涉及链表管理PCB的部分。 需要确保回答结构清晰,分点说明,并提供具体的示例代码和命令。同时,生成的相关问题要覆盖进程控制的其他方面,比如父子进程关系、PCB管理、进程调度算法比较等,帮助用户进一步探索。</think>以下是与操作系统实验中“进程控制”相关的教程及资料整理,结合实验目标、系统调用和示例代码进行说明: --- ### 一、进程控制实验核心知识点 1. **进程创建与终止** - **系统调用**:在Linux中使用`fork()`创建子进程,`exec()`系列函数加载新程序,`exit()`终止进程[^1]。 - **关键现象**:父进程通过`wait()`等待子进程结束,避免僵尸进程(Zombie Process)。 2. **进程控制块(PCB)** - **定义**:操作系统用PCB存储进程状态(运行、就绪、阻塞)、寄存器值、进程ID等信息。 - **数据结构**:实验中通常用链表模拟PCB队列,操作包括插入(创建进程)、删除(终止进程)、优先级调整[^1]。 3. **进程状态转换** - 实验需观察进程从创建(`fork()`)到终止(`exit()`)的状态变化,理解就绪队列、阻塞队列的调度逻辑。 --- ### 二、实验步骤与代码示例(Linux环境) #### 示例1:基础进程创建 ```c #include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main() { pid_t pid = fork(); // 创建子进程 if (pid == 0) { // 子进程分支 printf("Child Process PID: %d\n", getpid()); _exit(0); // 子进程终止 } else { // 父进程分支 wait(NULL); // 等待子进程结束 printf("Parent Process PID: %d\n", getpid()); } return 0; } ``` **观察重点**:去除`wait(NULL)`后运行多次,使用`ps aux`命令查看僵尸进程。 #### 示例2:模拟PCB链表操作 ```c typedef struct PCB { int pid; int status; // 0:就绪, 1:运行, 2:阻塞 struct PCB *next; } PCB; // 创建新进程并插入就绪队列 void create_process(PCB **head, int pid) { PCB *new_node = (PCB*)malloc(sizeof(PCB)); new_node->pid = pid; new_node->status = 0; new_node->next = *head; *head = new_node; } ``` --- ### 三、推荐参考资料 1. **教材章节** -操作系统概念》(恐龙书)第3章“进程管理” - 《现代操作系统》第2章“进程与线程” 2. **在线教程** - **GeeksforGeeks进程控制教程**:提供`fork()`、`exec()`的详细代码解析(英文)[^1]。 - **TutorialsPoint进程管理**:含流程图和系统调用对比(英文)。 3. **实验扩展** - **Linux内核源码**:查看`include/linux/sched.h`中`task_struct`的定义(PCB的实际实现)。 - **MIT 6.S081实验**:通过xv6操作系统实现进程调度(进阶内容)。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值