进程的创建与并发执行.docx
- 文档编号:25173002
- 上传时间:2023-06-05
- 格式:DOCX
- 页数:22
- 大小:75.57KB
进程的创建与并发执行.docx
《进程的创建与并发执行.docx》由会员分享,可在线阅读,更多相关《进程的创建与并发执行.docx(22页珍藏版)》请在冰豆网上搜索。
进程的创建与并发执行
实验二进程管理
2.1进程的创建与并发执行
1.实验目的
(1)加深对进程概念的理解,理解进程和程序的区别。
(2)认识并发进程的实质。
分析进程争用资源的现象,学习解决进程互斥的方法。
(3)理解系统调用和用户命令的区别。
2.实验类型:
验证型
3.实验学时:
2
4.实验原理和知识点
(1)实验原理:
程序的并发执行具有随机性和不可再现性。
程序并发执行会导致资源共享和资源竞争,各程序向前执行的速度会受资源共享的制约。
程序的动态执行过程用进程这个概念来描述。
由于向前推进的速度不可预知,所以多个进程并发地重复执行,整体上得到的结果可能不同。
但要注意,就其中某单个进程而言,其多次运行结果是确定的。
(2)知识点:
进程、子进程、并发执行的特性;
5.实验环境(硬件环境、软件环境):
(1)硬件环境:
IntelPentiumIII以上CPU,128MB以上内存,2GB以上硬盘
(2)软件环境:
linux操作系统。
6.预备知识
(1)fork()系统调用
头文件:
#include
/*是POSIX标准定义的unix类系统定义符号常量的头文件,包含了许多UNIX系统服务的函数原型,例如read函数、write函数和getpid函数*/函数原型:
pid_tfork(void);
/*是Linux下的进程号类型,也就是ProcessID_Type的缩写。
其实是宏定义的
unsignedint类型*/
函数功能:
fork的功能是创建子进程。
调用fork的进程称为父进程。
如图2.1所示。
子进程是父进程的一个拷贝,它继承了父进程的用户代码、组代码、环境变量、已打开的文件代码、工作目录及资源限制。
fork语句执行后,内核向父进程返回子进程的进程号,向子进程返回0。
父子进程都从fork()的下一句开始并发执行。
返回值:
返回值==-1:
创建失败。
返回值==0:
程序在子进程中。
返回值>0:
程序在父进程中。
(该返回值是子进程的进程号)
编程提示:
虽然子进程是父进程的一个复制品,但父子的行为是不同的。
编程时要抓住内核的返回值。
通过返回值,可以知道是父进程还是子进程,因而可以编写不同行为的代码。
⑵wait()系统调用
头文件:
#include
pid_twait(int*status);
发出wait调用的进程只要有子进程,就会睡眠
函数功能:
wait的功能是等待子进程结束。
直到子进程中的一个终止为止。
若没有子进程,则该调用立即返回。
函数参数:
status是子进程退出时的状态信息。
返回值:
成功则返回子进程号,否则返回-1。
⑶getpid()系统调用
头文件:
unistd.h,在VC++6.0下可以用process.h
函数原型:
pid_tgetpid(void);
函数功能:
wait的功能是将父进程挂起,等待子进程终止。
getpid函数用来取得目前进程
的进程ID,许多程序利用取到的此值来建立临时文件,以避免临时文件相同带来的问题。
返回值:
目前进程的进程ID。
(4)其他系统调用exit-终止进程
执行一个应用程序改变进程的优先
7.实验内容与步骤(将所有截图换成用户名为你们自己姓名的拼音,并回答所有的问题)
(1)运行图2.1所示程序
将图2.1中的源程序保存为e201.c
在终端中编译gccpe201e201.c
运行./e201
[yinji.aottYouYou']Sgcc-oe20ie201.c
IyinjiYouYou*)3./e201
son
father
此时,程序为死循环,在该终端中无法继续输入命令执行,于是,我们可以暂时不管这一个
终端,而是再新建一个终端,然后键入PS-3,列出当前所有进程
[yinJiaotYouYqu']Sps-c
FIDTTY
TIME:
CMD
1?
00s00:
00
init
2?
00:
00:
00
oisratian/O
3?
00:
00:
00
ksoftirqd/0
4?
00100:
00
*atchdlog/0
5?
00:
00:
00
events/O
6?
00:
00:
00
khelper
7?
OOsOOiOO
kLhread
]0?
00:
00:
00
kblockd/O
11?
00:
00:
00
kacpid
175?
DOiCiO:
00
cqueue/D
观察屏幕,是否有两个名为e201的进程。
比较它们的进程号,判别哪个是父进程,哪
个是子进程。
3713pts/1bash
3755pts/I00:
00:
00c201
3756pts/100i00:
23e2dl
3762pts/200;00;00bash
3790pts/200:
00:
00ps
[yinjiou"]S
[yinjiaotyouVou']Skill3755
[yinjltntYauYou"|Skill3756[ylnJiao»YouYou"]3ps-e
FIDTTVTIMECMD
1?
00:
00:
00init
2?
OO;00:
00migraildi)/0
3?
00:
00:
00ksoftirqd/0
程序中的while
(1);语句是为了不让程序退出来,以便于你观察进程状态。
用kill命令
把这两个进程终止。
可见,第一个终端如下图所示,已经从死循环中解救出来了。
[yinjiaotYouYou-Z&201
son
father
已终止
[yinji.noiiYouYdu*jS|
ctrl+c强制结束。
当然,最简单粗暴的方法不是关闭相关进程,而是直接通过对图2.1的程序稍加改进,可看见两个进程的进程号。
#include
intmain()
{
intpl:
pl=fork();
if(pi=e)
{
prlntf('son:
^dXn*(getpid(});
//whiled);
}
else
{
wait();
printf("father:
%d\n",getpid());}
[yinjiaoaYouYou"]Sgcc-ce20Ie201.cIyinjiao&YouYou*]$./e201
ton:
3B45
father:
a844
⑵编写一段名为e202.c的源程序,使用系统调用fork()创建两个子进程pl和p2。
pl的功能为显示字符'b',p2的功能为显示字符'c',父进程的功能为显示字符'a',父进程
和两个子进程并发运行。
不停的运行e202,观察并记录屏幕上的显示结果。
程序设计过程:
用while语句控制fork()直到创建成功。
用if语句判别是在子进程中还是在父进程中。
程序运行后会创建三个进程,它们分别是子进程pl、p2、父进程。
这三个进程并发运
行。
假定子进程有些任务要做,完成这些任务要花一定时间,因此,可以用一个延时函数简单地模拟这些任务。
〃e202.c
#include
voiddelay(intx)/*
{
inti,j;
for(i=0;i } intmain() { intp1,p2; while((p1=fork())==-1);/* if(p1==0)/* { delay(4096);/* putchar('b');/* }else{while((p2=fork())==-1);/*if(p2==0)/* { delay(2048);/* putchar('c');/* }else{ putchar('a');/* 延时函数*/ 创建子进程pl*/ 子进程pl创建成功*/ 子进程pl延时*/ 子进程pl显示字符'b'*/ 创建子进程p2*/ 子进程p2创建成功*/ 子进程p2延时*/ 子进程p2显示字符'c'*/ 父进程显示字符'a'*/ } } return0; } 按向上的光标键、回车,运行刚才的程序。 快速重复这个步骤,观察并记录结果。 [yinjiao^YouYou"]Sgcc-oe202 [yinjiao^YcuVou]S4/e202 bca[yinjiaottYouYou')S./e202 ca[1injiaofiiYouYou*]Sb./e2C2 a[yinjiao^YouYou~]$be./e202 a[yinJiao*YouYou'*]|Sbe./e202 a[yinjiaottYouYou"jshe./e202 a[yinjiao^YouYou~,|Sbe./e202 a[yinjiao*YouYou*]Sbe./e202 ba[yinjiaofiYauYou*]Sc./e202 ca[yinjiao®YouYolj"]$b-/e202 ca[yinJiao®YcuYou**]$b./e202 a[yinjiaottYouYou']$be./e202 请回答问题: 屏幕上是否有时显示bac,有时显示bca,…。 为什么会这样呢? (3)参考 (1)完成下列程序设计 父子进程同步实验: 编写一段程序,使用系统调用fork()创建一个子进程,子进程求 1+2+……+100的和并打印出来,使用系统调用wait()让父进程等待子进程结束。 请贴出源代码截图: ^include 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); }else{ waitO; prlntT("father;%d\n",getpid()): } ) 请贴出正确运行截图: [yinjiaottYouYou°t-oe203e203.c [yinjtaowYou\ou']S./e203 son: 674S 1-1-2+1-100=3050 father: 6747 [yintjiaottYouYou']S| (4)已知下列Linux程序执行后,运行结果如下,请画出进程家族树(以进程号标示进程,注意,每次运行进程号都不一样)。 //Linux程序 #include"stdio.h" #include"unistd.h" intmain() intp1,p2,p3; p1=fork(); p2=fork(); p3=fork(); //注: getpid()获取当前进程pid if(p1>0&&p2>0&&p3>0)printf("A: %d\n”,getpid());if(p1==0&&p2>0&&p3>0)printf("B: %d\n",getpid()); if(p1==0&&p2==0&&p3>0)printf("C: %d\n",getpid());if(p1==0&&p2==0&&p3==0)printf("D: %d\n",getpid()); if(p1==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)printf("H: %d\n",getpid());sleep(10); return0; } ■Is■VW [1injiaofiYouYou",/e204 Di8292 C1B291 L: 8293 B;8290 (3: 8295 F: 8294 11: 8296 A: 8289 [yinjiao^ouYou'| 这些进程构成的进程树为(要画出进程树才有加分哦! ): [yinJia0»Ycu¥ou']Spslree-p —■.『电、—■fJI;■Sis. IIJUnn_-UV-■IIIJl.I.JUAJIXJjf ^204(8292) -gn-: )mc-i5rntinal(6906)―nsh(6909)2 8290)―4: 8291 >-^204(8293)-^204: : 8294j—4: 8295) >-=204(6296) [yinjiaowYouYcu*|$pstree-pS2S9 e204(8289)—re204(8290J—re204(8291J—204(8292)^204(8293) ^204(8294)―204(8295) ^204(8296) [ylnjiao^YouYou]S| psf命令可以查看当前终端进程的进程数关系图 8•心得体会 附录pstree的用法 格式: pstree 以树状图显示进程,只显示进程的名字,且相同进程合并显示。 格式: pstree-p 以树状图显示进程,还显示进程PID。 格式: pstree 格式: pstree-p 以树状图显示进程PID为 附录Linux系统调用列表 以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数。 其中有一些函数的作用完全相同,只是参数不同。 (有点像C++函数重载,但是Linux核心是用C语言写的, 所以只能取成不同的函数名)。 还有一些函数已经过时,被新的更好的函数所代替了(gcc在链接这些函 数时会发岀警告),但因为兼容的原因还保留着,这些函数在前面标上“*号以示区别。 各系统调用的使用方法,可以通过man命令获得。 、进程控制: fork 创建一个新进程 clone 按指定条件创建子进程 execve 运行可执行文件 exit 中止进程 _exit 立即中止当前进程 getdtablesize 进程所能打开的最大文件数 getpgid 获取指定进程组标识号 setpgid 设置指定进程组标志号 getpgrp 获取当前进程组标识号 setpgrp 设置当前进程组标志号 getpid 获取进程标识号 getppid 获取父进程标识号 getpriority 获取调度优先级 setpriority 设置调度优先级 modify_ldt 读写进程的本地描述表 nanosleep 使进程睡眠指定的时间 nice 改变分时进程的优先级 pause 挂起进程,等待信号 personality 设置进程运行域 prctl 对进程进行特定操作 ptrace 进程跟踪 schedgetprioritymax 取得静态优先级的上限 sched_get_priority_min 取得静态优先级的下限 sched_getparam 取得进程的调度参数 sched_getscheduler 取得指定进程的调度策略 sched_rr_get_interval 取得按RR算法调度的实时进程的时间片长度 sched_setparam 设置进程的调度参数 sched_setscheduler 设置指定进程的调度策略和参数 sched_yield 进程主动让岀处理器,并将自己等候调度队列队尾 vfork 创建一个子进程,以供执行新程序,常与execve等同时使用 wait 等待子进程终止 wait3 参见wait waitpid 等待指定子进程终止 wait4 参见waitpid capget 获取进程权限 capset 设置进程权限 getsid 获取会晤标识号 setsid 设置会晤标识号 二、文件系统控制 1、文件读写操作 fcntl 文件控制 open 打开文件 creat 创建新文件 close 关闭文件描述字 read 读文件 write 写文件 readv 从文件读入数据到缓冲数组中 writev 将缓冲数组里的数据写入文件 pread 对文件随机读 pwrite 对文件随机写 lseek 移动文件指针 」seek 在64位地址空间里移动文件指针 dup 复制已打开的文件描述字 dup2 按指定条件复制文件描述字 flock 文件加/解锁 poll I/O多路转换 truncate 截断文件 ftruncate 参见truncate umask 设置文件权限掩码 fsync 把文件在内存中的部分写回磁盘 2、文件系统操作 access 确定文件的可存取性 chdir 改变当前工作目录 fchdir 参见chdir chmod 改变文件方式 fchmod 参见chmod chown 改变文件的属主或用户组 fchown 参见chown Ichown 参见chown chroot 改变根目录 stat 取文件状态信息 Istat 参见stat fstat 参见stat statfs 取文件系统信息 fstatfs 参见statfs readdir 读取目录项 getdents 读取目录项 mkdir 创建目录 mknod 创建索引结点 rmdir 删除目录 rename 文件改名 link 创建链接 symlink 创建符号链接 unlink 删除链接 readlink 读符号链接的值 mount 安装文件系统 umount 卸下文件系统 ustat 取文件系统信息 utime 改变文件的访问修改时间 utimes 参见utime quotactl 控制磁盘配额 三、系统控制 ioctl I/O总控制函数 sysctl 读/写系统参数 acct 启用或禁止进程记账 getrlimit 获取系统资源上限 setrlimit 设置系统资源上限 getrusage 获取系统资源使用情况 uselib 选择要使用的二进制函数库 ioperm 设置端口I/O权限 iopl 改变进程I/O权限级别 outb 低级端口操作 reboot 重新启动 swapon 打开交换文件和设备 swapoff 关闭交换文件和设备 bdflush 控制bdflush守护进程 sysfs 取核心支持的文件系统类型 sysinfo 取得系统信息 adjtimex 调整系统时钟 alarm 设置进程的闹钟 getitimer 获取计时器值 setitimer 设置计时器值 gettimeofday 取时间和时区 settimeofday 设置时间和时区 stime 设置系统日期和时间 time 取得系统时间 times 取进程运行时间 uname 获取当前UNIX系统的名称、版本和主机等信息 vhangup 挂起当前终端 nfsservctl 对NFS守护进程进行控制 vm86 进入模拟8086模式 create_module 创建可装载的模块项 delete_module 删除可装载的模块项 initmodule 初始化模块 querymodule 查询模块信息 *getkernelsyms 取得核心符号,已被querymodule代替 四、内存管理 brk 改变数据段空间的分配 sbrk 参见brk mlock 内存页面加锁 munlock 内存页面解锁 mlockall 调用进程所有内存页面加锁 munlockall 调用进程所有内存页面解锁 mmap 映射虚拟内存页 munmap 去除内存页映射 mremap 重新映射虚拟内存地址 msync 将映射内存中的数据写回磁盘 mprotect 设置内存映像保护 getpagesize 获取页面大小 sync 将内存缓冲区数据写回硬盘 cacheflush 将指定缓冲区中的内容写回磁盘 五、网络管理 getdomainname 取域名 setdomainname 设置域名 gethostid 获取主机标识号 sethostid 设置主机标识号 gethostname 获取本主机名称 sethostname 设置主机名称 六、socket控制 socketcall socket系统调用 socket 建立socket bind 绑定socket到端口 connect 连接远程主机 accept 响应socket连接请求 send 通过socket发送信息 sendto 发送UDP信息 sendmsg 参见send recv 通过socket接收信息 recvfrom 接收UDP信息 recvmsg 参见recv listen 监听socket端口 select 对多路同步I/O进行轮询 shutdown 关闭socket上的连接 getsockname 取得本地socket名字 getpeername 获取通信对方的socket名字 getsockopt 取端口设置 setsockopt 设置端口参数 sendfile 在文件或端口间传输数据 socketpair 创建一对已联接的无名socket 七、用户管理 getuid 获取用户标识号 setuid 设置用户标志号 getgid 获取组标识号 setgid 设置组标志号 getegid 获取有效组标识号 setegid 设置有效组标识号 geteuid 获取有效用户标识号 seteuid 设置有效用户标识号 setregid 分别设置真实和有效的的组标识号 setreuid 分别设置真实和有效的用户标识号
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 进程 创建 并发 执行