【操作系统】实验一 进程控制

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

四、实验过程及结果分析
(1)代码示例:

//example.c
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(void)
{
	pid_t pid=fork();
	if(pid==0){   
		printf("Child1 process! PID=%d  PPID=%d \n",getpid(),getppid()); 
		if(execl("./print","print","hello",NULL)==-1) 
			printf("execl failed!");	
		printf("where am I?");
	}else if(pid>0){
		pid_t pid2=fork();
		if(pid2==0){
			printf("Child2 process! PID=%d  PPID=%d \n",getpid(),getppid());
		}else if(pid2>0){
			wait();
			printf("Parent process! PID=%d  PPID=%d \n",getpid(),getppid()); 
			exit(0);
		}else{
			printf("fork faild\n");
			exit(0);
		}
	}else{
		printf("fork faild\n");
		exit(0);
	}
}

结果分析:

每次运行创建的子进程Childx process的PPID均为父进程Parent process的PID,说明两个子进程均为同一父进程创建。
每次运行的父进程Parent process的PPID均为34645,说明父进程也以子进程的形式存在,其父进程为同一系统进程。
第一个if代码段,调用了execl()函数,将当前进程child1替换掉,所以之后的"where am
I?”字符串并没有被输出,child1进程从print程序的main()开始执行,输出两个传参以及一段字符串,最终在main()的return
0;后结束
进程创建后由于父进程和子进程各自独立地进入就绪队列等待调度,所以谁会先得到调度是不确定,实验数据可以看出child1进程先运行和child2进程先运行各出现两次。
父进程代码段因为调用了wait()函数,等待子进程结束后函数返回继续执行原程序,输出相应信息,所以父进程字符串最后才输出。

(2)单进程:
示例代码:

//single.c
#include <stdio.h> 
#define NUM 5 
int main(void) 
{ 
	void print_msg(char *m); 
	print_msg("Good "); 
	print_msg("Morning  "); 
	print_msg("202008064307\n");  
	return 0; 
} 
void print_msg(char *m) 
{ 
	int i; 
	for(i = 0; i<NUM; i++){ 
		printf("%s",m); 
		fflush(stdout); 
		sleep(1);
	}
}

结果分析:执行按次序依次打印五次三个字符串
多进程:
示例代码:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(void){
	pid_t pid[3];
	int i;
	for(int i=0;i<3;i++){
		pid[i]=fork();
		if(pid[i]==0){
			break;//防止子进程再次创建子进程
		}
	}
	if(pid[0]==0){
		execl("print1","print","Good",NULL);	
	}else{
		if(pid[1]==0){
			execl("print1","print","Hello",NULL);		
		}else{
			if(pid[2]==0) execl("print1","print","202008064307",NULL);
			wait();
			wait();
			wait();//调用一次,只能回收一个子进程
			exit(0);
		}
	}
	return 0;
}

结果分析:

由于三个进程并发执行,所以时间上几乎是单个进程的1/3;不知道哪个进程先执行,因此打印结果无序。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值