1、实验三:进程同步实验一、实验任务:(1)掌握操作系统得进程同步原理;(2)熟悉liux得进程同步原语;(3)设计程序,实现经典进程同步问题。二、实验原理:(1)、V操作 PV操作由P操作原语与V操作原语组成(原语就是不可中断得过程),对信号量进行操作,具体定义如下: P(S):将信号量得值减1,即S=-1; 如果S0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。 V(S):将信号量得值加1,即S=S+; 如果S,则该进程继续执行;否则释放队列中第一个等待信号量得进程。(2)信号量信号量(semaoe)得数据结构为一个值与一个指针,指针指向等待该信号量得下一个进程。信号量得值与相应资
2、源得使用情况有关。当它得值大于0时,表示当前可用资源得数量;当它得值小于0时,其绝对值表示等待使用该资源得进程个数。注意,信号量得值仅能由P操作来改变。一般来说,信号量S0时,S表示可用资源得数量。执行一次P操作意味着请求分配一个单位资源,因此得值减1;当S0时,表示已经没有可用资源,请求者必须等待别得进程释放该类资源,它才能运行下去。而执行一个V操作意味着释放一个单位资源,因此S得值加1;若S0,表示有某些进程正在等待该资源,因此要唤醒一个等待状态得进程,使之运行下去。(3)liux得进程同步原语ait();阻塞父进程,子进程执行;#incude ss/type、h#icdeke_t fto
3、k(ca*pathname,chapj);它返回与路径ahnam相对应得一个键值。in ege(et key, int nes, it smflg) 参数ke就是一个键值,由ftok获得,唯一标识一个信号灯集,用法与mgge()中得key相同;参数nsems指定打开或者新创建得信号灯集中将包含信号灯得数目;seg参数就是一些标志位。参数k与sl得取值,以及何时打开已有信号灯集或者创建一个新得信号灯集与msgt()中得对应部分相同。该调用返回与健值相对应得信号灯集描述字。调用返回:成功返回信号灯集描述字,否则返回1。intsmop(int eid, sructsmuf *sops, unsied
4、 sps); smid就是信号灯集ID,sp指向数组得每一个smbuf结构都刻画一个在特定信号灯上得操作。nso为op指向数组得大小。int smcl(int semd,int emum,it md,unon smu rg) 该系统调用实现对信号灯得各种控制操作,参数semi指定信号灯集,参数md指定具体得操作类型;参数semum指定对哪个信号灯操作,只对几个特殊得cm操作有意义;ar用于设置或返回信号灯信息。三、实验源程序:#incdesystye、h#inclde#inlude#clue#iuesd、h#incl#ncldefcn、hilude#inclde ting、hinlud sys
5、/stat、h#iclde #nclue sys/sm、h#definPERMS_IRUS|_IWUSRdefin EMKEY(ey_)0x200tyedef uio _en int al; rut md_ *; ushrt*ray;semun; smid;statc in coun=0;ILE *fp,*p1,fp2;srct smbu prmut=,1,0,pwmutex=1,-,0,s=2,1,0;sruct semuf vrmutex=,1,0,vux=1,1,0,vs=,,;ntinitse() semun x; 、l1; if(sedsee(SEMEY,3,060|PCREAT|I
6、PC_EX))=-1) if(rro=EXIT) seid=seg(SEMKY,3,0); i(semc(si,0,ETVAL,x)=1) prrr(sectl flen); rturn(-1); (mctl(semid,1,SETVAL,x)=-1) eror(semcl fld); rtur(-1); f(sc(smid,2,SEVAL,x)-) perro(semctfailed); reur(1); rturn(sei);ain() t i,j,k; stic int 30; int hmi; nt*pit,*in2,addr,addr2;o(i0;i30;+) ai=;if((sd=
7、shet(IC_PRIVTE,4,PEM))=1) printf(tder,Creae Shae Meory Error:%na,srror(erno));exit(1); addr=hat(smid,,) ; pt=(int)ad; *int0; emd=iitsem(); i(or()=) /wrter semo(sid,pwmutx,); pif(clrier); fp1=foen(a、txt,w); for(k=;k0;k+) nf(fp1,% ,5*k); printf(wite %n ,*k); fclose(f1); prin(rie finish!!!n); semop(mid
8、,&vwuex,); ext(0); else if(ork()=) /rde mp(se,&prmute,1); adr=sht(shmi,0,0); it2=(in*)adr; if(*pin2=0) smp(semid,&pwmue,1); pit2=nt2+; prinf(rade1 enter- ot=%dn,*pi2); se(sid,vrmtx,); p=foen(a、tt,r); while(!feof(fp) fcanf(fp,d,); intf(eader 1 %dn ,i); semp(ed,&putx,1); *pit2*pin-1; printf(reader 1ex
9、it- cunt%d,2); countcont1; /rnf(cout=n,cout); if(*pint=) mop(smd,vwmute,1); semop(sei,vrmutex,1); et(); lse if(fork()=0) /rder seop(semi,pmutex,); dr2shmat(hmid,0,0); pit2=(t)ddr2; if(*pin2=0) smp(semi,&pwmute,1); *pnt2*int+; printf(Ra 2 enter+ count=dn,pit2); / rit(Rea2 coun=%,nt); /cont=2; /rintf(ount=d,cunt); semo(sei,&rmutex,); fp=fope(a、txt,r); while(!feo(p)) scanf(,%d ,i); prit(reder2 % ,i); semop(semid,&prmuex,1); /oun=ount-1; *pi2pn1; rintf(Rad2ext+ cou%dn,*pit); /int(Red2 cunt=%dn,coun); f(*pnt2=0) eop(semd,&wutex,1); semp(sei,&vrmtex,); exit(0); 四、实验结果: