最新进程的创建与并发执行-带答案版
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
p3=fork();
//注:getpid()获取当前进程pid
if(p1>0 && p2>0 && p3>0) printf("A:%d\n”,getpid()); if(p 1==0 && p2>0 && p3>0) printf("B:%d\n",getpid());
if(p 1==0 && p2==0 && p3>0) printf("C:%d\n",getpid()); if(p 1==0 && p2==0 && p3==0)printf("D:%d\n",getpid());
函数功能:fork的功能是创建 子进程 。调用fork的进程称为 父进程 。如图2.1所示。子 进程是父进程的一个拷贝,它继承了父进程的用户代码、 组代码、 环境变量、 已打开的文件 代码、工作目录及资源限制。fork语句执行后,内核向父进程返回子进程的进程号,向子 进程返回0。 父子进程都从fork()的下一句开始并发执行 。
3?00:00:00ksoftirqd/O
程序中的while(1);语句是为了不让程序退出来,以便于你观察进程状态ቤተ መጻሕፍቲ ባይዱ用kill命令
把这两个进程终止。可见,第一个终端如下图所示,已经从死循环中解救出来了。
[yinjiaotYouYou ']3-Z&201
son
father
已终止
[y inj i. noiiYouYd u *jS|
1+2+……+100的和并打印出来,使用系统调用wait()让父进程等待子进程结束。
请贴出源代码截图:
^include <stdlo.h>
intmain()
{
intpl;
pl=fork{);
if(pl==0){
inti;
intsum=01
Tor(i=i;i++)
(sum=sum+i;} printf("son:^d\n'fgetpidf));printf <" 1十2十十1£)百寻小\口*(sum);
IyinjiYouYou*)3./e201
son
father
此时,程序为死循环,在该终端中无法继续输入命令执行,于是,我们可以暂时不管这一个
终端,而是再新建一个终端,然后键入PS -3,列出当前所有进程
[¥i nj iYou "]$卩!t弋
FID TTYThtE:CMD
1?00:00:00I Hit
[yi nji aowYouYcu *|$ pstree -p S2S9
e204( 8289)—re204( 8290J—re204( 8291J—204( 8292) ^204(8293)
实验二 进程管理
2.1
1.实验目的
(1)加深对进程概念的理解,理解进程和程序的区别。
(2)认识并发进程的实质。分析进程争用资源的现象,学习解决进程互斥的方法。
(3)理解系统调用和用户命令的区别。
2.实验类型: 验证型
3.实验学时:2
4.实验原理和知识点
(1)实验原理: 程序的并发执行具有随机性和不可再现性。 程序并发执行会导致资源共享和 资源竞争, 各程序向前执行的速度会受资源共享的制约。 程序的动态执行过程用进程这个概 念来描述。 由于向前推进的速度不可预知, 所以多个进程并发地重复执行, 整体上得到的结 果可能不同。但要注意,就其中某单个进程而言,其多次运行结果是确定的。
if(p 1==0 && p2>0 && p3==0) printf("E:%d\n",getpid()); if(p1>0 && p2==0 && p3>0) printf("F:%d\n",getpid());
if(p1>0 && p2==0 && p3==0) printf("G:%d\n",getpid()); if(p1>0 && p2>0 && p3==0) prin tf("H:%d\n",getpid()); sleep(10);
3790 pts/200:00:00ps
[yi njiou"]S
[yinjiaotyouVou ']S kill 3755
[yi njltntYauYou"|S kill 3756 [ylnJiao»YouYou"]3ps -e
FIDTTVTIMECMD
1?00:00:00init
2?OO; 00:00 migraildi)/0
return 0;
}
■Is■V <WV<W
[yinJiaoftYouYou *]S,/e204
Di8292
C:B291
L:8293
B:8290
F:8294
11:8296
A:8289
[yinjiao^ouYou'|
这些进程构成的进程树为(要画出进程树才有加分哦!):
[yinJia0»Ycu¥ou ']S pslree -p
175 ?O0iC0:0OcQucue/ti
观察屏幕,是否有两个名为e201的进程。比较它们的进程号,判别哪个是父进程,哪
个是子进程。
3713pts/100;00:00bash
3755pts/I00:00:00c201
3756pts/100i00:23e2dl
3762 pts/200;00;00bash
和两个子进程并发运行。不停的运行e202,观察并记录屏幕上的显示结果。
程序设计过程:
用while语句控制fork()直到创建成功。用if语句判别是在子进程中还是在父进程 中。程序运行后会创建三个进程,它们分别是子进程pl、p2、父进程。这三个进程并发运
行。假定子进程有些任务要做, 完成这些任务要花一定时间, 因此,可以用一个延时函数简 单地模拟这些任务。
返回值:
返回值==-1:创建失败。
返回值==0: 程序在子进程中。
返回值>0: 程序在父进程中。 (该返回值是子进程的进程号)
编程提示: 虽然子进程是父进程的一个复制品,但父子的行为是不同的。编程时要抓住内 核的返回值。通过返回值,可以知道是父进程还是子进程,因而可以编写不同行为的代码。
⑵wait()系统调用
当然,最简单粗暴的方法不是关闭相关进程,而是直接通过 对图2.1的程序稍加改进,可看见两个进程的进程号。
#include <stdiorh>
intmain()
{
intpl:
pl=fork();
if(pi=e)
{
p rlntf(' son:^dXn *(getpid(});
//whiled);
}
else
〃e202.c
#i nclude <stdio.h>
void delay(i nt x)/*
{
int i,j;
for(i=0;i<x;i++) for(j=0;j<x;j++);
}
int mai n()
{
in t p1,p2;
while((p 1= fork())==-1);/*
if(p1==0)/*
ca[ yinjiao®YouYolj "]$ b-/e202
ca[ yinJiao®YcuYou **]$ b./e202
Ia[yinjiao^YouYoubc./e202
r一_-bJ
请回答问题:屏幕上是否有时显示bac,有时显示bca,…。为什么会这样呢?
(3)参考(1)完成下列程序设计
父子进程同步实验:编写一段程序,使用系统调用fork()创建一个子进程,子进程求
(4)已知下列Linux程序执行后,运行结果如下,请画出进程家族树(以进程号标示进程, 注意,每次运行进程号都不一样)。
//L in ux程序
#i nclude "stdio.h"
#i nclude "un istd.h"
int mai n()
{
in t p1,p2,p3;
p1= fork();
p2=fork();
(4)其他系统调用exit-终止进程
执行一个应用程序 改变进程的优先
7.实验内容与步骤(将所有截图换成用户名为你们自己姓名的拼音,并回答所有的问题)
(1)运行图2.1所示程序
将图2.1中的源程序保存为e201.c
在终端中编译gcc p e201 e201.c
运行./e201
[y in ji.aottYou You ']Sgcc-o e20i e201 .c
⑶getpid()系统调用
头文件:unistd.h,在VC++6.0下可以用process.h
函数原型:pid_t getpid(void);
函数功能:wait的功能是将父进程挂起,等待子进程终止。getpid函数用来取得目前进程
的进程ID,许多程序利用取到的此值来建立临时文件,以避免临时文件相同带来的问题。 返回值:目前进程的进程ID。
I[ yi njiao^YouYou "]S gcc -o e202 e202«c
I[yinjiao^YouYou ]S4/e2Q2
bca[yinjiaottYouYou ']$./e202
ca[ i i nji aofiiYouYou *]S b. /e2C2
Ia[yinji ao^YcuYou']S bc・/e202
{
wait();
printf(" fathe r:%d\n",getpid());}
[yi nji aoaYouYou "]S gcc -c e20Ie201.c I yinjiao&YouYou *]$ ./e201
ton:3B45
father:a844
⑵编写一段名为e202.c的源程序,使用系统调用fork()创建两个子进程pl和p2。pl的功能为显示字符'b',p2的功能为显示字符'c',父进程的功能为显示字符'a',父进程
}else{
waitO;
prlntT("father;%d\n",getpid()):
}
)
请贴出正确运行截图:
[yinjiaottYouYou°t -o e203 e203.c
[yi njtaowYou\ou ']S./e203
son:674S
1-1-2+1-100=3050
father:6747
[yintjiaottYouYou']S|
—■.『电、—■ fJI;■Sis.
IIJU nn_- UV-■IIIJl.I.JU A JIXJ jf
-gn-:)mc-i5rnti nal (6906)―nsh(6909)2<U(B289)―204:8290)―4:,8291
>-^204(8293) -^204::8294j—4:8295)
>-=204(6296)
{
delay(4096);/*
putchar('b');/*
}else{ while((p2=fork())==-1); /* if(p2==0)/*
{
delay(2048);/*
putchar('c');/*
}else{
putchar('a');/*
}
}
return0;
}
按向上的光标键、回车,运行刚才的程序。快速重复这个步骤,观察并记录结果。
Ifl[y inJiao* You You '* ]|S be. /e202
*1 yinjiaottYouYou "]S he./e202
a[ yi nji ao<»YouYou*Sbe-/e202
a[ yinjiaoftYouYcu * S be,/e202
ba[sinjiao^YcuYou *]S c./e202
/*是POSIX标准定义的unix类系统定义符号常量的头文件,包含了许多UNIX系统服务 的函数原型,例如read函数、write函数和getpid函数*/函数原型:pid_t fork(void);
/*是Linux下的进程号类型,也就是Process ID_Type的缩写。其实是宏定义的
unsigned int类型*/
2?00:00:00misrntinn/O
3?00:00:00ksoftirqd/O
4?00:00:00•fitchdoE/O
5?00:00:00events/0
6?00:00:00khelper
7?00:00:00kthread
10?00:00:00kblcKkd/O
11?00:00:00kacpid
头文件:#in clude <sys/wait.h>函数原型:pid_t wait(i nt *status);
函数功能:wait的功能是等待子进程结束。
直到子进程中的一个终止为止。若没有子进程,则该调用立即返回。
函数参数:status是子进程退出时的状态信息。
返回值:成功则返回子进程号,否则返回-1。
(2)知识点:进程、子进程、并发执行的特性;
5.实验环境(硬件环境、软件环境) :
(1)硬件环境:Intel Pentium III以上CPU,128MB以上内存,2GB以上硬盘
(2)软件环境:linux操作系统。
6.预备知识
(1)fork()系统调用
头文件:#include <unistd.h>unix standard header
//注:getpid()获取当前进程pid
if(p1>0 && p2>0 && p3>0) printf("A:%d\n”,getpid()); if(p 1==0 && p2>0 && p3>0) printf("B:%d\n",getpid());
if(p 1==0 && p2==0 && p3>0) printf("C:%d\n",getpid()); if(p 1==0 && p2==0 && p3==0)printf("D:%d\n",getpid());
函数功能:fork的功能是创建 子进程 。调用fork的进程称为 父进程 。如图2.1所示。子 进程是父进程的一个拷贝,它继承了父进程的用户代码、 组代码、 环境变量、 已打开的文件 代码、工作目录及资源限制。fork语句执行后,内核向父进程返回子进程的进程号,向子 进程返回0。 父子进程都从fork()的下一句开始并发执行 。
3?00:00:00ksoftirqd/O
程序中的while(1);语句是为了不让程序退出来,以便于你观察进程状态ቤተ መጻሕፍቲ ባይዱ用kill命令
把这两个进程终止。可见,第一个终端如下图所示,已经从死循环中解救出来了。
[yinjiaotYouYou ']3-Z&201
son
father
已终止
[y inj i. noiiYouYd u *jS|
1+2+……+100的和并打印出来,使用系统调用wait()让父进程等待子进程结束。
请贴出源代码截图:
^include <stdlo.h>
intmain()
{
intpl;
pl=fork{);
if(pl==0){
inti;
intsum=01
Tor(i=i;i++)
(sum=sum+i;} printf("son:^d\n'fgetpidf));printf <" 1十2十十1£)百寻小\口*(sum);
IyinjiYouYou*)3./e201
son
father
此时,程序为死循环,在该终端中无法继续输入命令执行,于是,我们可以暂时不管这一个
终端,而是再新建一个终端,然后键入PS -3,列出当前所有进程
[¥i nj iYou "]$卩!t弋
FID TTYThtE:CMD
1?00:00:00I Hit
[yi nji aowYouYcu *|$ pstree -p S2S9
e204( 8289)—re204( 8290J—re204( 8291J—204( 8292) ^204(8293)
实验二 进程管理
2.1
1.实验目的
(1)加深对进程概念的理解,理解进程和程序的区别。
(2)认识并发进程的实质。分析进程争用资源的现象,学习解决进程互斥的方法。
(3)理解系统调用和用户命令的区别。
2.实验类型: 验证型
3.实验学时:2
4.实验原理和知识点
(1)实验原理: 程序的并发执行具有随机性和不可再现性。 程序并发执行会导致资源共享和 资源竞争, 各程序向前执行的速度会受资源共享的制约。 程序的动态执行过程用进程这个概 念来描述。 由于向前推进的速度不可预知, 所以多个进程并发地重复执行, 整体上得到的结 果可能不同。但要注意,就其中某单个进程而言,其多次运行结果是确定的。
if(p 1==0 && p2>0 && p3==0) printf("E:%d\n",getpid()); if(p1>0 && p2==0 && p3>0) printf("F:%d\n",getpid());
if(p1>0 && p2==0 && p3==0) printf("G:%d\n",getpid()); if(p1>0 && p2>0 && p3==0) prin tf("H:%d\n",getpid()); sleep(10);
3790 pts/200:00:00ps
[yi njiou"]S
[yinjiaotyouVou ']S kill 3755
[yi njltntYauYou"|S kill 3756 [ylnJiao»YouYou"]3ps -e
FIDTTVTIMECMD
1?00:00:00init
2?OO; 00:00 migraildi)/0
return 0;
}
■Is■V <WV<W
[yinJiaoftYouYou *]S,/e204
Di8292
C:B291
L:8293
B:8290
F:8294
11:8296
A:8289
[yinjiao^ouYou'|
这些进程构成的进程树为(要画出进程树才有加分哦!):
[yinJia0»Ycu¥ou ']S pslree -p
175 ?O0iC0:0OcQucue/ti
观察屏幕,是否有两个名为e201的进程。比较它们的进程号,判别哪个是父进程,哪
个是子进程。
3713pts/100;00:00bash
3755pts/I00:00:00c201
3756pts/100i00:23e2dl
3762 pts/200;00;00bash
和两个子进程并发运行。不停的运行e202,观察并记录屏幕上的显示结果。
程序设计过程:
用while语句控制fork()直到创建成功。用if语句判别是在子进程中还是在父进程 中。程序运行后会创建三个进程,它们分别是子进程pl、p2、父进程。这三个进程并发运
行。假定子进程有些任务要做, 完成这些任务要花一定时间, 因此,可以用一个延时函数简 单地模拟这些任务。
返回值:
返回值==-1:创建失败。
返回值==0: 程序在子进程中。
返回值>0: 程序在父进程中。 (该返回值是子进程的进程号)
编程提示: 虽然子进程是父进程的一个复制品,但父子的行为是不同的。编程时要抓住内 核的返回值。通过返回值,可以知道是父进程还是子进程,因而可以编写不同行为的代码。
⑵wait()系统调用
当然,最简单粗暴的方法不是关闭相关进程,而是直接通过 对图2.1的程序稍加改进,可看见两个进程的进程号。
#include <stdiorh>
intmain()
{
intpl:
pl=fork();
if(pi=e)
{
p rlntf(' son:^dXn *(getpid(});
//whiled);
}
else
〃e202.c
#i nclude <stdio.h>
void delay(i nt x)/*
{
int i,j;
for(i=0;i<x;i++) for(j=0;j<x;j++);
}
int mai n()
{
in t p1,p2;
while((p 1= fork())==-1);/*
if(p1==0)/*
ca[ yinjiao®YouYolj "]$ b-/e202
ca[ yinJiao®YcuYou **]$ b./e202
Ia[yinjiao^YouYoubc./e202
r一_-bJ
请回答问题:屏幕上是否有时显示bac,有时显示bca,…。为什么会这样呢?
(3)参考(1)完成下列程序设计
父子进程同步实验:编写一段程序,使用系统调用fork()创建一个子进程,子进程求
(4)已知下列Linux程序执行后,运行结果如下,请画出进程家族树(以进程号标示进程, 注意,每次运行进程号都不一样)。
//L in ux程序
#i nclude "stdio.h"
#i nclude "un istd.h"
int mai n()
{
in t p1,p2,p3;
p1= fork();
p2=fork();
(4)其他系统调用exit-终止进程
执行一个应用程序 改变进程的优先
7.实验内容与步骤(将所有截图换成用户名为你们自己姓名的拼音,并回答所有的问题)
(1)运行图2.1所示程序
将图2.1中的源程序保存为e201.c
在终端中编译gcc p e201 e201.c
运行./e201
[y in ji.aottYou You ']Sgcc-o e20i e201 .c
⑶getpid()系统调用
头文件:unistd.h,在VC++6.0下可以用process.h
函数原型:pid_t getpid(void);
函数功能:wait的功能是将父进程挂起,等待子进程终止。getpid函数用来取得目前进程
的进程ID,许多程序利用取到的此值来建立临时文件,以避免临时文件相同带来的问题。 返回值:目前进程的进程ID。
I[ yi njiao^YouYou "]S gcc -o e202 e202«c
I[yinjiao^YouYou ]S4/e2Q2
bca[yinjiaottYouYou ']$./e202
ca[ i i nji aofiiYouYou *]S b. /e2C2
Ia[yinji ao^YcuYou']S bc・/e202
{
wait();
printf(" fathe r:%d\n",getpid());}
[yi nji aoaYouYou "]S gcc -c e20Ie201.c I yinjiao&YouYou *]$ ./e201
ton:3B45
father:a844
⑵编写一段名为e202.c的源程序,使用系统调用fork()创建两个子进程pl和p2。pl的功能为显示字符'b',p2的功能为显示字符'c',父进程的功能为显示字符'a',父进程
}else{
waitO;
prlntT("father;%d\n",getpid()):
}
)
请贴出正确运行截图:
[yinjiaottYouYou°t -o e203 e203.c
[yi njtaowYou\ou ']S./e203
son:674S
1-1-2+1-100=3050
father:6747
[yintjiaottYouYou']S|
—■.『电、—■ fJI;■Sis.
IIJU nn_- UV-■IIIJl.I.JU A JIXJ jf
-gn-:)mc-i5rnti nal (6906)―nsh(6909)2<U(B289)―204:8290)―4:,8291
>-^204(8293) -^204::8294j—4:8295)
>-=204(6296)
{
delay(4096);/*
putchar('b');/*
}else{ while((p2=fork())==-1); /* if(p2==0)/*
{
delay(2048);/*
putchar('c');/*
}else{
putchar('a');/*
}
}
return0;
}
按向上的光标键、回车,运行刚才的程序。快速重复这个步骤,观察并记录结果。
Ifl[y inJiao* You You '* ]|S be. /e202
*1 yinjiaottYouYou "]S he./e202
a[ yi nji ao<»YouYou*Sbe-/e202
a[ yinjiaoftYouYcu * S be,/e202
ba[sinjiao^YcuYou *]S c./e202
/*是POSIX标准定义的unix类系统定义符号常量的头文件,包含了许多UNIX系统服务 的函数原型,例如read函数、write函数和getpid函数*/函数原型:pid_t fork(void);
/*是Linux下的进程号类型,也就是Process ID_Type的缩写。其实是宏定义的
unsigned int类型*/
2?00:00:00misrntinn/O
3?00:00:00ksoftirqd/O
4?00:00:00•fitchdoE/O
5?00:00:00events/0
6?00:00:00khelper
7?00:00:00kthread
10?00:00:00kblcKkd/O
11?00:00:00kacpid
头文件:#in clude <sys/wait.h>函数原型:pid_t wait(i nt *status);
函数功能:wait的功能是等待子进程结束。
直到子进程中的一个终止为止。若没有子进程,则该调用立即返回。
函数参数:status是子进程退出时的状态信息。
返回值:成功则返回子进程号,否则返回-1。
(2)知识点:进程、子进程、并发执行的特性;
5.实验环境(硬件环境、软件环境) :
(1)硬件环境:Intel Pentium III以上CPU,128MB以上内存,2GB以上硬盘
(2)软件环境:linux操作系统。
6.预备知识
(1)fork()系统调用
头文件:#include <unistd.h>unix standard header