ImageVerifierCode 换一换
格式:DOCX , 页数:15 ,大小:25.33KB ,
资源ID:4114585      下载积分:8 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/4114585.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(实验题目:进程管理及进程通信.docx)为本站上传会员【a199****6536】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

实验题目:进程管理及进程通信.docx

1、实验题目:进程管理及进程通信 姓名 学号 实验日期 2016/10/12 实验环境: VMware Workstation中的Ubuntu 64位操作系统。 实验目的: 利用Linux提供的系统调用设计程序,加深对进程概念的理解.体会系统进程调度的方法和效果. 了解进程之间的通信方式以及各种通信方式的使用。 实验内容: 用vi 编写使用系统调用的C 语言程序。 操作过程及结果: 实验1: 编写程序.显示进程的有关标识(进程标识、组标识、用户标识等)。经过5 秒钟后,执行另一个程序,最后按用户指示(如:Y/N

2、结束操作. 结果: 实验2: 编写程序。实现父进程创建一个子进程。体会子进程与父进程分别获得不同返回值,进而执行不同的程序段的方法。 结果: 思考:子进程是如何产生的?又是如何结束的?子进程被创建后它的运行环境是怎样建立的? 答:是由父进程用fork()函数创建形成的,通过exit()函数自我结束,子进程被创建后核心将其分配一个进程表项和进程标识符,检查同时运行的进程数目,并且拷贝进程表项的数据,由子进程继承父进程所有文件。 实验3: 编写程序.父进程通过循环语句创建若干子进程。探讨进程的家族树以及子进程继承父进程的资源的关系。 结果: 思考:① 画出进程的家族树.子

3、进程的运行环境是怎样建立的?反复运行此程序看会有什么情况?解释一下。 ② 修改程序,使运行结果呈单分支结构,即每个父进程只产生一个子进程。画出进程树,解释该程序。 答1: 反复运行,子进程的编号在不断变化,但是初始的父进程的编号不会变,因为:父进程始终是该程序在虚拟机操作系统下的进程号,但是子进程是该父进程创建的子进程不断增加而得的,子进程的编号应该是顺序递增的. 答2: #include 〈stdio。h〉 #include 〈sys/types。h〉 #include 〈

4、unistd.h> main() { int i, pid; for (i=1; i<4; i++) if (pid=fork()) break; } 实验4: 编写程序.使用fork( )和exec( )等系统调用创建三个子进程。

5、子进程分别启动不同程序,并结束。反复执行该程序,观察运行结果,结束的先后,看是否有不同次序。 结果: 思考:子进程运行其它程序后,进程运行环境怎样变化的?反复运行此程序看会有什么情况?解释一下。 答:子进程运行其他程序后,这个进程就完全被新程序代替。由于并没有产生新进程所以进程标识号不改变,除此之外的旧进程的其他信息,代码段,数据段,栈段等均被新程序的信息所代替。新程序从自己的main()函数开始进行。反复运行此程序发现结束的先后次序是不可预知的,每次运行结果不一样。原因是当每个子进程运行其他程序时,他们的结束随着其他程序的结束而结束,所以结束的先后次序在改变。 实验5: 编写程序

6、验证子进程继承父进程的程序、数据等资源。如用父、子进程修改公共变量和私有变量的处理结果;父、子进程的程序区和数据区的位置。 结果: 思考:子进程被创建后,对父进程的运行环境有影响吗?解释一下。 答:子进程被创建后,对父进程的运行环境无影响,因为当子进程在运行时,他有自己的代码段和数据段,这些都可以作修改,但是父进程的代码段和数据段是不会随着子进程数据段和代码段的改变而改变。 实验6: 复习管道通信概念,编写一个程序。父进程创建两个子进程,父子进程之间利用管道进行通信。要求能显示父进程、子进程各自的信息,体现通信效果。 结果: 思考:①什么是管道?进程如何利用它进行通信的?解释

7、一下实现方法。 ②修改睡眠时机、睡眠长度,看看会有什么变化。请解释。 ③加锁、解锁起什么作用?不用它行吗? 答1:管道:是指能够连接一个写进程和一个读进程、并允许它们以生产者—消费者方式进行通信的一个共享文件,又称为pipe文件。由于写进程从管道的入端将数据写入管道,而读进程则从管道的出端读出数据.进程利用管道进行通信:将索引结点中的直接地址项作为一个循环队列来管理,为它设置一个读指针,一个写指针,按先进先出的顺序读写.在该例中,利用fd[2]这个数组来确定读写替换。执行进程1时,lockf(fd[1],1,0)使得管道写入端加锁,这样就可以进行写入了,write(fd[1],buf,5

8、0); /*信息写入管道*/ lockf(fd[1],0,0); /*管道写入端解锁*/这样其他进程就能继续进行读写操作了。然后执行进程2的写入,过程同上。最后父进程的进行读,read(fd[0],s,50)。读写之间、写和写之间也是互斥的,多以会加锁. 答2: 修改1号子进程的睡眠时间长度修改为20s后,等待了较长时间,然后出现了下面的结果:2号子进程先执行了,然后父进程执行。原因应该是:父进程进行wait()等待子进程,由于2号子进程的睡眠时间短,于是就先执行完了2号子进程的内容,然后才第二次wait()时才执行1号子进程,最后父进程结尾。 答3:加锁解锁的作用:为了使得读、写进程能够

9、互斥的访问pipe文件,每逢继承访问pipe文件前,都需检查该索引节点是否已经上锁,若已经锁住,进程便睡眠等待;否则,将索引节点上锁,然后再进行读、写操作,操作结束后又将该索引节点解锁,并唤醒因该节点上锁而睡眠的进程。这样就能实现了读、写之间的互斥操作,每次只能有一个进程进行访问pipe文件. 实验7: 编程验证:实现父子进程通过管道进行通信.进一步编程,验证子进程结束,由父进程执行撤消进程的操作。测试父进程先于子进程结束时,系统如何处理“孤儿进程”的。 只要在父进程后加上wait()函数,然后打印“子进程已经结束”,一旦子进程结束,父进 程撤销进程.当父进程先于子进程终止时.所有子

10、进程的父进程改变为init进程称为进程由init进程领养. 实验8: 编写两个程序,一个是服务者程序,一个是客户程序。执行两个进程之间通过消息机制通信。消息标识MSGKEY 可用常量定义,以便双方都可以利用.客户将自己的进程标识(pid)通过消息机制发送给服务者进程。服务者进程收到消息后,将自己的进程号和父进程号发送给客户,然后返回.客户收到后显示服务者的pid 和ppid,结束。 结果: 思考:想一下服务者程序和客户程序的通信还有什么方法可以实现?解释一下你的设想,有兴趣试一试吗。 答:还可以通过管道操作。或者用信号量机制来实现.信号量是一个整形计数器,用来控制多个进程对共享资源

11、的访问。或者通过消息队列信号机制,通过向消息队列发送信息、接收信息来实现进程间的通信。 实验9: 编程实现软中断信号通信.父进程设定软中断信号处理程序,向子进程发软中断信号。子进程收到信号后执行相应处理程序。 结果: 思考:这就是软中断信号处理,有点儿明白了吧?讨论一下它与硬中断有什么区别?看来还挺管用,好好利用它。 答:软中断发生的时间是由程序控制的,而硬中断发生的时间是随机的.软中断是由程序调用发生的,而硬中断是由外设引发的。 实验10:用信号量机制编写一个解决生产者-消费者问题的程序。 研究并讨论: 1。 讨论Linux 系统进程运行的机制和特点,系统通过什么来管理进程?

12、 系统通过进程控制块(PCB)来管理进程.PCB主要分为四部分:(1)进程表项,(2)U区,(3)系统区表,(4)进程区表。 2。C语言中是如何使用Linux 提供的功能的?用程序及运行结果举例说明。 Linux 系统的一种用户接口是程序员用的编程接口,即系统调用。系统调用的目的 是使用户可以使用操作系统提供的有关进程控制、文件系统、输入输出系统、设备管理、 通信及存储管理等方面的功能,而不必涉及系统内部结构和硬件细节,大大减少用户程序 设计和编程难度. Linux 的系统调用以标准实用子程序形式提供给用户在编程中使用。一般使用系统调 用应注意以下三点:(1)函数所在的头文件(2

13、函数调用格式,包括参数格式、类型.(3)返回值格式、类型。 例如:程序:在该程序中调用了系统程序”date”。 #include 〈unistd。h〉 main() { execlp(”date”,”date”,(char *)0); return; } 结果如下: 3.什么是进程?如何产生的?举例说明。 答: 进程实体是程序段、相关的数据段和PCB三部分构成的实体。进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。进程的产生:进程是由创建而产生的,即使进程实体运行时而产生的。例如:父进程通过fork()程序创建一个子进程. 4。进程控制如何实现的?

14、举例说明。 答:进程控制一般由OS的内核中的原语来实现的。例如:用完了I/O设备的进程调用原语weakup(),将等待该事件的进程唤醒. 5.进程通信方式各有什么特点?用程序及运行结果举例说明. 答:通信方式有:(1)共享存储器系统:相互通信的进程共享某些数据结构或共享存储区,进程之间能够通过这些空间进行通信。(2)消息传递系统:源程序可以直接或间接地将消息传送给目标进程.(3)管道通信系统:能够连接一个写进程和一个读进程、并允许它们以生产者—消费者方式 进行通信的一个共享文件,又称为pipe文件。由于写进程从管道的入端将数据写入管道,而读进程则从管道的出端读出数据。 6。管道通信如

15、何实现?该通信方式可以用在何处? 答:实现:(1)互斥,即当一个进程正在对pipe执行读/写操作时其它进程必须等待;(2)同步,指当写(输入)进程把一定数量的数据写入pipe时,便去睡眠等待,知道读(输出)进程取走数据后,再把它唤醒。当读进程读一空pipe时,也应睡眠等待,直至写进程将数据写入管道后,才将之唤醒;(3)确定对方是否存在,只有确定了对方已存在时,才能进行通信。用法:用于链接一个读进程和一个写进程以实现它们之间的通信的一个共享文件。 7。什么是软中断?软中断信号通信如何实现? 答:每个信号读对应一个正整数常量,代表同一用户的诸进程之间传送事先约定的信息的类型,用于通知某进程发

16、生了某一场时间。每个进程在运行时,都要通过信号量机制来检查是否有信号到达。若有,便中断正在执行的程序,转向与该信号对应的处理程序,以完成对该事件的处理,处理结束后再返回到原来的断电继续执行.实质上,信号机制是对中断机制的一种模拟. 体会: 在本次实验中,我利用Linux提供的系统调用设计程序,加深了对进程概念的理解,也体会到了系统进程调度的方法和效果,还了解了进程之间的通信方式以及各种通信方式的使用。虽然在实验的过程中遇到很多困难,但是还好有张涛老师的悉心指点和网上资料的帮助,使我能渡过难关,圆满完成本次实验,在此也向他们说一声感谢。 附录:(源程序) 1、 #include 〈s

17、tdio。h> #include 〈stdlib。h〉 #include 〈unistd.h> #include

18、0) { exit(1); } wait(0); printf("Do you want to stop the process?\n”); char x; scanf(”%c",&x); if(x == ’y’) exit(0); return 0; } 2、 #include #include 〈unistd。h〉 #include 〈wait.h〉 int main() { int i; if (fork()) { i

19、 wait(0); printf("It is parent process.\n”); printf(”The child process,ID number %d, is finished.\n”,i); } else { printf(”It is child process.\n"); sleep(10); exit(0); } } 3、 #include 〈stdio。h〉 #include 〈stdlib。h> #include

20、std。h〉 #include

21、wait(0); printf(”%d:The chile %d is finished。\n”,getpid(),j); } } 4、 #include 〈stdio。h〉 #include 〈stdlib。h〉 #include

22、d1=fork(); if(child_pid1==0) { execlp("echo”,”echo”,"child process 1",(char *)0); perror(”exec1 error。\n ”); exit(1); } child_pid2=fork(); if(child_pid2==0) { execlp(”date”,”date”,(char *)0); perror(”exec2 err

23、or。\n ”); exit(2); } child_pid3=fork(); if(child_pid3==0) { execlp(”ls”,"ls",(char *)0); perror(”exec3 error.\n ”); exit(3); } puts(”Parent process is waiting for chile process return!"); while((pid=wait(&status))!=—1)

24、{ if(child_pid1==pid) printf("child process 1 terminated with status %d\n”,(status>〉8)); else { if(child_pid2==pid) printf(”child process 2 terminated with status %d\n”,(status〉>8)); else

25、 { if(child_pid3==pid) printf(”child process 3 terminated with status %d\n” ,(status>〉8)); } } } puts("All child processes terminated。"); puts(”Parent process terminated."); exit(0); } 5、 #include

26、h> #include 〈stdlib.h> #include 〈unistd.h〉 #include int globa=4; int main(void) { pid_t pid; int vari=5; printf(”before fork。\n”); if ((pid=fork())<0) { printf("fork error。\n”); exit(0); } else if(pid==0)

27、 { globa++; vari——; printf("Child %d changed the vari and globa.\n”,getpid()); } else printf("Parent %d did not changed the vari and globa.\n”,getpid()); printf(”pid=%d, globa=%d, vari=%d\n”,getpid()

28、globa,vari); exit(0); } 6、 #include #include 〈stdlib。h〉 #include 〈unistd。h> #include

29、lockf(fd[1],1,0); sprintf(buf,"Child process P1 is sending messages! \n"); printf(”Child process P1! \n”); write(fd[1],buf,50); lockf(fd[1],0,0); sleep(5); j=getpid(); k=getppid(); printf(”P1 %d is weakup. My parent process

30、 ID is %d.\n”,j,k); exit(0); } else { while((p2=fork())==-1); if(p2==0) { lockf(fd[1],1,0); sprintf(buf,"Child process P2 is sending messages! \n”); printf(”Child process P2! \n”); write(fd[

31、1],buf,50); lockf(fd[1],0,0); sleep(5); j=getpid(); k=getppid(); printf(”P2 %d is weakup。 My parent process ID is %d.\n”,j,k); exit(0); } else { l=getpid();

32、 wait(0); if(r=read(fd[0],s,50)==-1) printf(”Can’t read pipe。 \n”); else printf("Parent %d: %s \n",l,s); wait(0); if(r=read(fd[0],s,50)==—1) printf(”Can’t read pipe. \n”);

33、 else printf(”Parent %d: %s \n”,l,s); exit(0); } } } 7、 8、 服务器程序: #include #include 〈unistd.h> #include

34、Y 75 struct msgform { long mtype; char mtext[256]; }msg; int msgqid; int main() { int i,pid,* pint; extern cleanup(); for(i=0;i〈20;i++) signal(i,cleanup); msgqid=msgget(MSGKEY,0777|IPC_CREAT); for(;;) { msgrcv(msgqid,&msg,25

35、6,1,0); pint=(int *)msg.mtext; pid=*pint; printf("Server :receive from pid %d\n",pid); msg。mtype=pid; *pint=getpid(); msgsnd(msgqid,&msg,sizeof(int),0); } } cleanup() { msgctl(msgqid,IPC_RMID,0); exit(0); } 客户端程

36、序: #include 〈stdio.h〉 #include #include〈sys/ipc。h〉 #include〈sys/msg.h〉 #define MSGKEY 75 struct msgform { long mtype; char mtext[256]; }; int main(void) { struct msgform msg; int msgqid,pid,*

37、pint; msgqid=msgget(MSGKEY,0777); pid=getpid(); pint=(int *)msg.mtext; *pint=pid; msg.mtype=1; msgsnd(msgqid,&msg,sizeof(int),0); msgrcv(msgqid,&msg,256,pid,0); printf(”Clint : receive from pid %d\n",* pint); } 9、 #include

38、b.h> #include #include #include〈sys/msg。h> #define MSGKEY 75 int main(void) { int i,j,k; int func(); signal(18,func()); if(i=fork()) { j=kill(i,18); printf("Parent: signal 18 ha

39、s been sent to child %d,returned %d.\n",i,j); k=wait(0); printf(”After wait %d,Parent %d: finished.\n",k,getpid()); } else { sleep(10); printf(”Child %d: A signal from my parent is recived。\n”,getpid()); } } func() { int m;

40、 m=getpid(); printf(”I am Process %d: It is signal 18 processing function.\n”,m); } 10、 #include 〈stdio.h> #include 〈stdlib.h〉 #include #include 〈signal.h> #define N 5 // 消费者或者生产者的数目 #define M 10 // 缓冲数目 int in = 0;

41、 // 生产者放置产品的位置 int out = 0; // 消费者取产品的位置 int buff[M] = { 0 }; // 缓冲初始化为0,开始时没有产品 sem_t empty_sem; // 同步信号量,当满了时阻止生产者放产品 sem_t full_sem; // 同步信号量,当没产品时阻止消费者消费 pthread_mutex_t mutex; // 互斥信号量,一次只有一个线程访问缓冲 int product_id = 0; //生产者 id int prochase_id = 0; //消费者id //信号处理函数 void Han

42、dlesignal(int signo){ printf(”程序退出\n”,signo); exit(0); } /* 打印缓冲情况 */ void print() { inti; printf("产品队列为"); for(i = 0; i < M; i++) printf("%d”, buff[i]); printf(”\n”); } /* 生产者方法 */ void *product() { int id = ++pr

43、oduct_id; while(1) {//重复进行 //用sleep的数量可以调节生产和消费的速度,便于观察 sleep(2); sem_wait(&empty_sem); pthread_mutex_lock(&mutex); in= in % M; printf(”生产者%d在产品队列中放入第%d个产品\t”,id, in); buff[in

44、]= 1; print(); ++in; pthread_mutex_unlock(&mutex); sem_post(&full_sem); } } /* 消费者方法 */ void *prochase() { intid = ++prochase_id; while(1) {//重复进行 //用sleep的数量可以调节生产和消费的速度,便于观察

45、 sleep(5); sem_wait(&full_sem); pthread_mutex_lock(&mutex); out= out % M; printf(”消费者%d从产品队列中取出第%d个产品\t",id, out); buff[out]= 0; print(); ++out; pthread_mutex_

46、unlock(&mutex); sem_post(&empty_sem); } } int main() { printf("生产者和消费者数目都为5,产品缓冲为10,生产者每2秒生产一个产品,消费者每5秒消费一个产品,Ctrl+退出程序\n"); pthread_tid1[N]; pthread_tid2[N]; inti; intret[N]; //结束程序 if(signal(SIGINT,Handlesignal)==

47、SIG_ERR){//按ctrl+C产生SIGINT信号 printf(”信号安装出错\n”); } // 初始化同步信号量 intini1 = sem_init(&empty_sem, 0, M);//产品队列缓冲同步 intini2 = sem_init(&full_sem, 0, 0);//线程运行同步 if(ini1 && ini2 != 0) { printf("信号量初始化失败!\n”); exit(1); } //

48、初始化互斥信号量 intini3 = pthread_mutex_init(&mutex, NULL); if(ini3 != 0) { printf(”线程同步初始化失败!\n"); exit(1); } // 创建N个生产者线程 for(i = 0; i 〈 N; i++) { ret[i]= pthread_create(&id1[i], NULL, product, (void *) (&i));

49、 if(ret[i] != 0) { printf(”生产者%d线程创建失败!\n”, i); exit(1); } } //创建N个消费者线程 for(i = 0; i 〈 N; i++) { ret[i]= pthread_create(&id2[i], NULL, prochase, NULL); if(ret[i] != 0) { printf(”消费者%d线程创建失败!\n”, i); exit(1); } } //等待线程销毁 for(i = 0; i 〈 N; i++) { pthread_join(id1[i], NULL); pthread_join(id2[i],NULL); } exit(0); }

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服