2023年操作系统实验报告完整版.pdf
翼J球)卷 匕 孝h BEIJING UNIVERSITY OF TECHNOLOGY操作系统实验报告学 号:_ _ _ _ _ _ _ _ _ _ _ _ _ _ _姓 名:_ _ _ _ _ _ _ _ _ _ _ _ _ _ _指导老师:_ _ _ _ _ _ _ _ _ _ _ _ _ _完毕日期:目录实验一 1实验二。2实 验 三7实 验 四10实验五。15实 验 六18实 验 七22实验一 UNIX/LINUX入门一、实验目的了 解 UNIX/LINUX运营环境,熟悉U N IX/L IN U X 的常用基本命令,熟悉和掌握U N IX/L IN U X 下c 语言程序的编写、编译、调试和运营方法。二、实验内容。熟 悉 UNIX/L I N U X 的常用基本命令如l s、who、pwd、p s 等。练 习 UN IX/LIN U X 的文本行编辑器v i 的使用方法熟 悉 UNIX/LINUX 下c 语言编译器c c/g c c 的使用方法。用v i编写一个简朴的显示“Hello,World!”c语言程序,用g c c 编译并观测编译后的结果,然后运营它。三、实验规定按照规定编写程序,放在相应的目录中,编译成功后执行,并按照规定分析执行结果,并写出实验报告。四、实验程序#inclu d e#in c 1 u de int main()(print f(H He 1 1 o World!n );retur n 0;五、实验感想通过第一次室验,我了解UNIX/LINUX运营环境,熟悉了UNIX/L IN U X 的常用基本命令,熟悉和掌握了 UNIX/L I N U X 下c语言程序的编写、编译、调试和运营方法。实验二进程管理一、实验目的加深对进程概念的理解,明确进程与程序的区别;进一步结识并发执行的实质。二、实验内容(1)进程创建编写一段程序,使用系统调用fork()创建两个子进程。当此程序运营时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示“a”;子进程分别显示字符 b 和字符“c”。试观测记录屏幕上的显示结果,并分析因素。(2)进程控制修改已编写的程序,将每一个进程输出一个字符改为每一个进程输出一句话,再观测程序执行时屏幕上出现的现象,并分析因素。(3)进程的管道通信编写程序实现进程的管道通信。使用系统调用p ip e。建立一个管道,二个子进程P 1 和P2 分别向管道各写一句话:C h i Id 1 is s e n d i n g a message!Child 2 i s s e n d i n g a m e s s a g e!父进程从管道中读出二个来自子进程的信息并显示(规定先接受P l,再接受P 2).三、实验规定按照规定编写程序,放在相应的目录中,编译成功后执行,并按照规定分析执行结果,并写出实验报告。四、实验设计1、功能设计(1)进程创建使用f o r k ()创建两个子进程,父进程等待两个子进程执行完再运营。(2)进程控制使用f o r k ()创建两个子进程,父进程等待两个子进程分别输出一句话再运营。(3)进程的管道通信先创建子进程1 ,向管道写入一句话,子进程1 结束后创建子进程2,向管道写入一句话,最后父进程从管道中读出。2、数据结构子进程和管道。3、程序框图创建子进程2“五、实验程序(1)进程创建#i n c l u d e#i n c 1 u d e i n t m a i n()I i n t p i d l,p i d 2;p i d l=f o r k();i f (p i d 1 0)w a i t (N U L L);。p i d 2 =f o r k();i f (p i d 2 0)w a i t(N U L L);p ri n t f (,za n ,*);e x i t (0);)(2)进程控制#i n c l u d e#i n c l u d e i n t m a i n ()i n t p i d 1,p i d 2;叩i d l=f o r k ();i f (p i d 1 0)w a i t(N U L L);i d 2 =f o r k ();i f (p i d 2 0)w a i t(N U L L);p r i n t f (Z/T h i s i s f a t h e r a n u);e x i t(0 );)(3)进程的管道通信#i n c l u d e#i n c l u d e#i n c 1 u d e#i n c l u d e i n t m a i n ()Io i n t p i d 1,p i d 2;i n t p f d 2;0c h a r *m s g 1=C h i I d 1 i s s e n d i n g a m e s s a g e!;c h a r *m s g 2=C h i I d 2 i s s e n d i n g a m e s s a g e 1 ;c h a r b u f 256;i n t r,w;i f (p i p e (p f d)0)p r i n t f (z,p i p e c r e a t e e r r o r!n,z);e x i t (1);)p i d 1=f o r k ();o i f (p i d l 0)p r i n t f(F o r k 1 f a i l e d !H);i f (p i d l =O)c l o s e(p f d 0 );/w r i t es l e e p(3);i f (w=w r i t e (p f d 1 ,m s g 1,s t r l e n (m s g 1)0)Iw a i t (N U L L);p i d 2=f o r k();i f (p i d 2 0)c l o s e (p f d l );/r e a ds l e e p (3);i f (r=r e a d (p f d 0 ,b u f,256)0)p r i n t f (r e a d e r r o r!nz/);e x i t(1);)e l s e p r i n t f (p a r e n t r e a d from p i p e:%s n ,b u f);w a i t (N U L L);c l o s e(p f d l );/r e a ds 1 e e p(3);i f (r =r e a d (p f d 0 ,b u f,25 6)0)p r i n t f (/z r e a d e r r o r!n);e x i t(1);e 1 s e p r i n t f (p a r e n t read f r o m pipe:%s n ,b u f);)i f(p i d 2=0)c l o s e (p f d 0);/w r i t es l e e p(6);i f (w =w r i t e(p f d l ,m s g 2,s t r 1 e n(m s g 2)0)p r i n t f (w r i t e e r r o r!n );e x i t(l);e l s e p r i n t f (c h i l d 2 s e n d m s g t o p i p e !n );e x i t (0);)六、实验结果文 件(F)编 辑(E)查 看(V)终 端(T)帮 助(H)wj5swj5swj5swj5s-$gcc shiyan2.c./shiyan2El画囱,-o shiyan20awj5swj5s$gcc shiyan2.c-o shiyan2wj5swj5s-$./shiyan2bcawj5swj5s$nwj5swj5s:文件(F)编辑(E)查看(V)终端(T)帮助(H)wj5swj5s$gcc shiyan2.c-o shiyan2wj5swj5s./shiyan2This is child bjThis is child c(This is father awj5swj5s$口。从图中可以看出,分别输出了,三个字母,三句话,实现了子进程向管道写数据,父进程从管道中读出。七、实验感想通过本次实验,我们对进程的概念加深了理解,熟悉了进程的创建方法与作用机制,明确了进程与程序的异同。同时,我们掌握了使用管道通信的机制,进一步结识了并发执行的实质。实验三一个进程启动另一个程序的执行一、实验目的编 写Linux环境下,fork。与exec()的结合使用实现一个进程启动另一个程序的执行的基本方法,掌握ex e c()的几种调用方法。二、实验内容父进程从终端读取要执行的命令,并交给子进程执行 父进程等待子进程结束,并打印子进程的返回值。三、实验规定按照规定编写程序,放在相应的目录中,编译成功后执行,并按照规定分析执行结果,并写出实验报告。四、实验设计1、功能设计根据实验规定,父进程和子进程将被分派不同的任务:父进程从终端读取要执行的命令交给子进程,然后等待子进程技术打印子进程的返回值;子进程执行父进程读取的命令并返回给父进程。由于子进程执行命令需要打开其他文献,所以需要使用e xe c()类的函数实现在一个进程来启动另一个程序,在这里应使用ex eel p()函数从P A TH环境变量中查找文献并执行。对于父进程,可以调用f get()从终端读取要执行的命令,以字符串形式存储然后交给子进程执行,待子进程执行完毕后接受子进程返回值并打印。由于规定带参数的命令也可以执行,那么需要在父进程中fet s 两次,第一次gets得到命令给串command,然后get s 参数给串c 0 m m an d l,并且将这两个参数分别传到子进程的ex e c()函数,其中前两个都是command,第三个是 commandl。2、数据结构用 ch a r*型全局变量command存放指令用 char*型全局变量comman d 1 存放参数3、程序框图五、实验程序#i n e l u d e#i n c l u de#i n cl u de#i n cl u dech a r co m m a n d 2 5 6;c h a r co m m a n d 1 25 6;i n t m a i n()Ii n t r t n;/子进程的返回数值。i n t er r o r n o;o w h i l e(1)P r i n t f (z,z,);8/从终端读取要执行的命令o f g e t s(co m m a n d,2 5 6,s t d in);p r i n t ls m s gc t rl()编制长度为 IK的消息的发送和接受程序。2 .共享存储取得创建、附接和断接使用系统调用 s h m g e t()、s h mat()s hmctl()、s hmc t 1 (),编制一个与上述功能相同的程序。三、实验规定按照规定编写程序,放在相应的目录中,编译成功后执行,并按照规定分析执行结果,并写出实验报告。四、实验设计1、消息的创建、发送和接受(1)功能设计为了实现进程之间消息的创建、发送和接受,一方面应定义两个子进程,S erv er进程负责发送,C I ie n t进程负责接受,父进程负责创建。另一方面需要用到msgget()、msgsn d()、msggrevO、ms g ctr 1 ()等函数进行对消息的控制。题目规定消息长度为1 K,那么ms g sn d(id,msgp,s i ze,f 1 ag)和msgrc v(i d,ms g p,s i ze,typ e,flag)函数中参数 s i ze应设为1024,msgget(key,f 1 a g)中的key应 为 75。父进程获得创建消息后,子进程S er v e r 先后发送编号为1 10的 1 0 条消息,子进程C 1 ie n t先后接受这1 0 条消息,方能达成实验目的。(2)数据结构消息(mymsg):结构体实现,包含的成员变量有消息类型和消息内容,具体实现如下:s tr u c t mymsg a /消息的结构体声明lo n g i n t m y m s g ty p e;。消息类型i nt t ext;。;。消息内容(3)程序框图002、共享存储区的创建、附接和断接(1)功能设计为了实现进程通过共享存储区进行通信,需要创建两个进程并且调用s h m g e t()、sh m a t()、shm ctl()函数实现共享存储区的创建、附接和断接。由于共享存储区的写入和读取由两个子进程完毕,而共享存储区在本程序中为所有进程共用的,因此共享存储区的创建、附接和断接均需要在父进程中完毕。具体的实现方式是现在父进程中创建一块共享存储区,然后用i n t 类型指针lis t 指向该存储区的地址;接着创建两个子进程,第一个子进程通过1 i s t 指针实现向共享存储区写入i n t 类型的数据,第二个子进程通过li s t 指针实现从共享存储区读出i n t 类型的数据。由于两个子进程同时使用了 1 i s t 指针,所以需要控制两个进程互斥,在读进程序中添加了 s le e p(l)语句。(2)数据结构通 过 shmid=shm g et(key,s i ze,f 1 ag)函数建立(获得)共享存储区,返回该共享存储区的描述符shmido(3)程序框图五、实验程序1、消息的创建、发送和接受#i n c l u d e#i n c 1 u d e#i n c l u d e#i n c l u d e#i n c l u d e#i n c 1 u d e#d e f i n e M A X 1 0 2 4#d e f i n e K E Y 7 5s t r u c t m y m s g 。/消息结构体l o n g i n t m y m s g t y p e;a/消息类型i n t t e x t ;o 。消息内容 m s g;i n t m ai n()(p i d _ t p i d s;p i d _ t p i d c;i n t m s g i d;i n t i=l;m s g i d=m s g g e t(K E Y,0 6 6 6|I P C _ C R E A T);/获得一个消息的描述符i f (p i d s=f o r k()=0 )“/创建S e r v e r 子进程o w h i l e (i l l)m s g.m y m s g t y p e=l l-i;g m s g.t e x t =i ;p r i n t f (t h e s e n d e d m e s s a g e i s%d t h n ,i);i+;m s g s n d (m s g i d,&m s g,M A X,0);/向 m s g i d 指定的消息队列发送消息,长度为I K)e x i t (0 );o e 1 s e i=1 0;i f (p i d c=f o r k ()=0)创建 C l i e n t 子进程w h i l e(i!=1)msg r e v (m s g i d,&m s g,M A X,0,0);从m s g i d指定的消息队列接受消息p r i n t f (t h e m e s s ag e i s%d t h n H,m s g.t e x t );i=m s g.m y m s g t y p e;g e x i t (0);e l s e w a i t (0);w ai t (0);e x i t (0);)2、共享存储区的创建、附接和断接#i n c l u d e#i n c 1 u d e#i n c 1 u d e#i n c 1 u d e#i n c l u d e#i n c l u d e#i n c l u d e#d e f i n e M A X 1 1#d e f i n e K E Y 7 5m a i n()n t i ,c h i 1 d 1 ,c h i l d 2,r u n n i n g=l ;定义子进程号o i n t i d ;i n t *l i s ti d=s h m g e t (K E Y,s i z e o f (i n t)*M A X,I P C _ C R E A T|0 6 6 6);建立一块共享存储区,返回该共享存储区的描述符i do 1 i s t=(i n t*)s h m a t(i d,0,0);将 1 i s t 指针指向共享存储区i f (c h i l d l =f o r k ()=-1 )p r i n t f (,z e r r o r i n f o r k a n );e x i t (1);)i f(c h i l d l=0)s l e e p(l);。f o r(i=0;i =1 0;i +)s p r i n t f (y o u r m e s s a g e i s:%d n ,1 i s t i );e x i t (0);e l s e f (c h i l d 2=f o r k()=1)p r i n t f (,z e r r o r i n f o r k an H);e x i t (1);。i f (c h i l d 2 =0)i=0;w h i l e (1)o l i s t i =i;向缓冲区里写入数据p r i n t f (t h e m e s s ag e s e n t i s :%d n”,l i s t i );o t,i f(l i s t i =1 0)br e ak;i +;。)e x i t (0 );)o e l s e w a i t (0);w ai t (0);s h m d t (l i s t);/将共享存储区与进城断开o s h m c t l(i d,I P C _ R M I D,0);/将共享存储区标志为被销毁的e x i t (0);)I六、实验结果(1)消息的创建、发送和接受root()ch en g m in 01:-/D es kto p/s h fy an-OX文件 编 转 查看9 终 端 标 签 帮助the sended message is 1 ththe sended message is 2 ththe sended message is 3 ththe sended message is 4 ththe sended message is 5 ththe sended message is 6 ththe sended message is 7 ththe sended message is 8 ththe sended message is 9 ththe sended message is 10 ththe message is 1 ththe message is 2 ththe message is 3 ththe message is 4 ththe message is 5 th第一个子进程一次发了 10条消息,第二个子进程一次接受了 10条消息,消息队列先进先出。(2)共享存储区的创建、附接和断接rootchengminOL:/Desktop/shlyan-0X文件编 辑 查 看 终 端 标 签 帮 助 回the message sent is:0the message sent is:1the message sent is:2the message sent is:3the message sent is:4the message sent is:5the message sent is:6the message sent is:7the message sent is:8the message sent is:9the message sent is:10your message is:0your message is:1your message is:2your message is:3your message is:4your message is:5your message is:6your message is:7your message is:8your message is:9your message is:10rootOchengminOl shiyan#|第一个子进程向共享存储区写入了 11个数据,第二个子进程从共享存储区读取,两个进程之间是互斥执行的。七、实验感想通过本次实验,我学会了如何用消息队列和共享内存的方式实现进程间的通信,掌握了Li n u x系统的消息通信机制和共享存储区的原理,并在实践过程中掌握了它们的使用方法。在编程和调试的过程中,我进一步熟悉了 LINUX环境下的编译过程和调试方法。实验五运用信号实现进程间通信一、实验目的学 习U N I X类操作系统信号机制,编写L i n u x环境下运用信号实现进程间通信的方法,掌握注册信号解决程序及s i gna 1 ()调用方法。二、实验内容编写一个程序,完毕下列功能:实现一个SIGINT信号的解决程序,注册该信号解决程序,创建一个子进程,父子进程都进入等待。S IG IN T信号的解决程序完毕的任务涉及打印接受到的信号的编号和进程PID。编译并运营该程序,然后在键盘上敲Ctrl+C,观测出现的现象,并解释。提醒:参见“五、补充材料”中的signal。的基本用法。三、实验规定按照规定编写程序,放在相应的目录中,编译成功后执行,并按照规定分析执行结果,并写出实验报告。四、实验设计1、功能设计本实验规定运用信号实现进程间通信。为了实现实验目的,需要实现一个S IG IN T信号的解决函数func()并注册该信号解决函数。信号解决函数需要完毕的任务应涉及打印接受到的信号的编号和进程的PID,所以func()函数应能实现打印当前进程的p id以及根据接受到的信号的编号打印出该信号名称的功能。父进程和子进程分别接受两个不同的信号,因此两个进程调用s ig n a 1 ()函数时应为不同的信号注册信号解决函数。本次实验采用了 S IG IN T和SIGUSR 1两个信号。为了让父子进程都可以接受到信号,在注册信号解决函数后应让两个进程进入等待,并且为了方便验证实验结果,让父进程接受S IG IN T信号,子进程接受SIGUSR 1信号。2、数据结构信号(SIG N AL):UN I X系统具有2 0种信号。可以使用si g n al()函数为每个信号注册信号解决函数。3、程序框图五、实验程序#i n clude#i n c lu d e#i n clude#in c 1 u d e void func(int i);i nt p id;i n t main()(-if(P i d=f ork()=0)创建子进程(printf(uson p id:%d n,pid);/打印子进程号signal(SIG USR1,f un c);/注册 S I GU S RI 的信号解决程序。f or(;)子进程进入等待叩 a us e();)e 1 se。printf(fatherpid:%d n,p i d);/打印父进程号。sig n al(SIG I N T,f u n c);。注册 SIGINT 的信号解决程序-fo r(;;)/父进程进入等待P au s e();)void func(i n t i)信号解决函数o p ri n t f(p i d:%d n ,p i d);oi f (i=S I G U S R 1)p ri n t f (nre c e i v e d S I G U S R 1 n );oe l s e i f (i =S I G U S R 2)叩ri n t f(re c e i v e d S I G U S R 2 n );e 1 s e i f(i =S I G I N T)(oop r i n t f (*r e c e i v e d S I G I N T%dn”,i );on e x i t(l);)e e x i t(0 );)六、实验结果wj5swj5s:文件(F)编辑(E)查看(V)终端(T)帮助(H)wj5swj5s*$v i shiyan5.cwj5swj5s*$gcc shiyanS.c-o shiyanSwj5swj5s-$./shiyan5fatherpid:2472sonpid:6ACpid:2472received SIGINT 2wj5swj5s*$./shiyan5&1 2473wj5swj5s$fatherpid:2474sonpid:0k ill-USR1 2472bash:k ill:(2 4 7 2)-没 有 那 个进 程wj5swj5s$k ill-USR1 2474wj5swj5s j$pid:6received SIGUSR1人Cw j5sM 5s 】$口如图所示,第一次执行后打印父进程和子进程p i d,按Ctr l+c后,父进程接受信号,信号解决程序输出父进程号2 472和信号名称。第二次使用./sh i y a n5&后台运营此程序,使 用 k i l l -USR 1 2472时,子进程接受信号,信号解决程序输出子进程号0,并输出信号名称。七、实验心得通过本次实验,我掌握了注册信号解决程序及s ignal()调用方法,并且了解了如何让程序在后台运营的方法。我也进一步了解了 L I N U X 系统中进程同步与通信的原理。实验六线程的创建一、实验目的编 写 Linu x 环境下的多线程程序,了解多线程的程序设计方法,掌握最常用的三个函数p t hrea d _ create,pthre a d_j o in 和 p th r ead_e x i t 的用法。二、实验内容1、主程序创建两个线程myTh r e a d 1 和m y Th r ea d 2,每个线程打印一句话。使用 pth r ead_ c r e a te(&i d,NULL,(v o id *)thr e a d,NU LL)完毕。2、创建两个线程,分别向线程传递如下两种类型的参数。传递整型值传递字符三、实验规定按照规定编写程序,放在相应的目录中,编译成功后执行,并按照规定分析执行结果,并写出实验报告。四、实验设计1、创建两个进程每个进程打印一句话(1)功能设计题目规定创建两个线程,每个线程打印一句话,可以认为两个线程的功能是相同的,故只需要写一个线程的运营函数th read。,在这个函数里有一个p rin t f输出一句话即可。然后 在main函数里分别创建两个线程,然后等待两个线程结束。(2)数据结构线程:使用pth read _create()创建。每个线程有相应的线程标示符,也有各自的属性。线程可以和线程运营函数绑定,并可以在创建线程时拟定该线程运营函数的参数。(3)程序框图开始一定义线程标识符2创建线程1并与thread()a数绑定a创建线程2并与thread(旗数绑定等待线程结束一2T 可线程传递如下两种类型的参数:整型值、字符(J 结M题目规定创建两个线程,两个线程分别传递i n t型 和c h a r型数据给线程运营函数。所以要编写两个不同的线程运营函数分别接受i n t型和char型的数据。相应的p thread_crea te ()函数中要给第四个参数,作为形参传进线程运营函数。(2)数据结构线程:同 1,使用P t h read.create。创建。每个线程有相应的线程标示符,也有各自的属性。线程可以和线程运营函数绑定,并可以在创建线程时拟定该线程运营函数的参数。(3)程序框图五、实验程序1、创建两个进程每个进程打印一句话#i nc 1 u d e#i nclude#inc 1 u de void thr e ad()。/线程运营函数(p ri n tf(Thi s is a p thread.n);。输出一句话)i n t m a i n()(pthre a d _t i d 1,i d2;“/定义两个线程标记符int i,ret;。r e t=pthread_creat e(&i d 1,NU L L,(void*)th r ea d,NULL);创建线程标记为idlif (re t!=0)卜 /线程创建失败printf(Crea t e p t hre a d error!n);exit(1);)ret=p t h re a d_c r eate(&id2,NULL,(voi d*)thread,NULL);创建线程标记为 id2if(ret!=0)。“/线程创建失败。0 叩 r i ntf(rea t e pt h read e rror!nM);。exit(1);00 p ri n t f(This i s t h e m a i n pr o cess.nu);叩thread_Join(id 1 ,NULL);等待第一个线程结束叩th re a d oin(id2,N U L L);/等待第二个线程结束re t u rn(0);)2、创建两个进程每个进程打印一句话分别向线程传递如下两种类型的参数:整型值、字符#include#i nc 1 ude#in c lude#i n c 1 ud e void t hreadc h ar(ch a r*c)。/接受字符的线程运营函数 p r i n t f(r ec e i ve a char:%cnu,c);void threa d i nt(int*i)。接受整数的线程运营函数pr i ntf(nreceive a int:%dnH,i);int main(void)p t hr e ad_ t idl,id 2;i n t ret;c h a r c=T;char*a=c“/定 义 char*指针变量传参数用ret=p thread_ e re ate(&id 1 ,NULL,(vo i d*)thre a dchar,a);/创建线程1,第四个参数为c har大型变量用来传递字符if(re t!=0)。/线程创建失败pr i n tf(*C r e ate pthre a d er r o r!nn);e xi t(1);)i n t i=99;int*b=i;。/定 义 i nt*指针变量传参数用re t=p t h read_create(&i d 2,NULL,(void*)t h r ead i nt,b);。创建线程2,第四个参数为im大型变量用来传递字符if(re t!=0)线程创建失败。叩 r intf(C r e a t e p t h r ea d er r or!n);oexi t(1 );printf(nThis is t he main p roc e ss.n*);p t hread o in(i dl,NULL);/等待线程 1 结束pthre a d _ j oin(id 2,NU L L);等待线程 2 结束r e t u m(0);六、实验结果_ r x文件(F)编辑(E)查看(V)终端(T)帮助(H)wj5swj5s vi shiyan6.cwj5swj5s j$gcc shiyan6.c-tpthread-o shiyan6wj5swj5s j$,/shiyan6This is a pthread.This is the main process.This is a pthread.wj5swj5s$口由图可知两个线程主程序创建了两个进程这两个进程分别输出了一句话。画文件(F)编瑁(E)查看(V)终端(T)帮助(H)wj5swj5s$vi shiyane.c 0wj5swj5s j$gcc shiyane.c-Ipthread-o shiyaneshiyan6.c:在 函 数main中:shiyane.c:37:警 告:初 始 化 时 将 整 数 赋 给 指 针,未 作 类 型 转 换shiyan6.c:52:警 告:初 始 化 时 将 整 数 赋 给 指 针,未 作 类 型 转 换wj5swj5s$./shiyaneThis is the main process.receive a char:treceive a int:99Wj5swj5s$口主程序分别创建了两个线程并向线程1 传递了 一 向线程2 传递了 9 9,线程运营函数分别输出告知接受了这两个参数。七、实验感想通过本次实验,我学会了如何使用L IN U X 下的线程创建函数pthread_ create。来创建线程,并且向线程传递参数。同时更加纯熟的使用LINUX。实验七运用信号量实现进程的控制一、实验目的学 习 U N IX 类操作系统信号量机制,编写L in u x 环境下运用信号量实现进程控制的方法,掌握相关系统调用的使用方法。二、实验内容创建4 个线程,其中两个线程负责从文献读取数据到公共的缓冲区,另两个线程从缓冲区读取数据作不同的解决(加和乘运算)。使用信号量控制这些线程的执行。三、实验规定按照规定编写程序,放在相应的目录中,编译成功后执行,并按照规定分析执行结果,并写出实验报告。四、实验设计1、功能设计题目规定创建4 个线程,其中两个负责从文献读数据到缓冲区,另两个负责从缓冲区读数据进行加和乘的运算。我对这4 个线程进行如下安排,线 程 1 读后线程2 才可以读,线程2 读了后线程3 才可以进行加的运算,线程3 加完了后线程4 才干进行乘的运算,线程4 乘完后线程1才干继续读。故需4 个信号量seml,sem 2,sem3,s em4。线 程 1 消费sem 1 生产s e m 2,线程2 消费s em 2生产s e m 3,线程3 消费sem 3 生产sem4,线程4 消费s e m 4生产sem1,形成一个循环,直到文献结束为止。2、数据结构信号量(s e map h ore):数据类型为结构s em_t,本质上是一个长整型的数。一共4 个公共缓冲区(s t a c k):采 用 2维数组的方式实现(s t a c k N U M 2 )。数组中的两列分别存储两个文献中的数据。该 2 维数组尚有一个索引:siz e,指向2维数组的顶部。读线程每次从文献读出两个数放到s t a c k N U M 0 和 s t a c k N U M 1 五、实验程序#i n c l u d e#i nc 1 u d e#i nc l u d e#d e f i ne M A X 10i nt o p e r a nd MAX 2;i n t s i z e =0;s e m _ t s e m;v o i d R e a d Da t a l (v o i d)FILE*f p=f o p e n(1.d a t ”,r);o w h i l e (!f e o f (f p )。f s c a nf (f p,d%d u,&o p e r a nd s i z e 0 ,&o p e r a nd s i z e 1);o i f (f e o f (f p)break;+s i z e;。s e m _ p o s t (&s e m);)f c l o s e(f p);)v o i d R e a d Da t a 2(v o i d)F I LE*f p=f open (2.d a t ,r );w h i l e(!f e o f(f p )f s c a n f (f p,z%d%d/,,&o p e r a nd s i z e 0 ,&o p e r a n d s i z e 1);i f (f e o f (f p)b r e a k;+s i z e ;s e m _ p o s t (&s e m);)f c 1 o s e (f p );)v o i d Ha nd l e Da