linux多线程试验报告_第1页
linux多线程试验报告_第2页
linux多线程试验报告_第3页
linux多线程试验报告_第4页
linux多线程试验报告_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

《物联网工程领域应用综合实训》实验报告《物联网工程领域应用综合实训》实验报告/18#defineSHM_MODE0600#defineSEM_MODE0600#defineSEM_FULL0#defineSEM_EMPTY1#defineMUTEX2/*#ifdefined(__GNU_LIBRARY__)&&!defined(_SEM_SEMUN_UNDEFINED)//unionsemunisdefinedbyincluding<sys/sem.h>#else//accordingtoX/OPENwehavetodefineitourselvesunionsemun{intval;structsemid_ds*buf;I... ? . 1 1.Junsignedshort*array;};#endifunionsemunsu;//sem口口出必用于初始化信号量*/structmy_buffer{inthead;inttail;charstr[MAX_BUFFER_SIZE];intnum;〃缓冲区里字母数量intis_empty;};constint『CONSUMER=2;//消费者数量constintN_PRODUCER=2;//生产者数量constintN_BUFFER=10;//缓冲区容量constintN_WORKTIME=10;//工作次数intshm_id=-1;intsem_id=-1;pid_tchild;pid_tparent;〃得到10以内的一个随机数intget_random()JTOC\o"1-5"\h\z: :intdigit; : : :srand((unsigned)(getpid()+time(NULL)));digit=rand()%10; I I Iiireturndigit; i i iI[CI 〃得到A〜Z的一个随机字母 | | |i i char getRandChar() i i ir■《| | charletter; | | || | srand((unsigned)(getpid() +time(NULL))); I I I! ! letter=(char)((rand()% 26)+'A'); ! ! !returnletter; | | |J//sem_id表示信号量集合的id//sem_num表示要处理的信号量在信号量集合中的索引 ! ! !//P操作voidwaitSem(intsem_id,intsem_num){ I I I| | structsembufsb; | | |sb.sem_num=sem_num;| 工 sb.sem_op=-1;//表示要把信号量减一 | | |sb.sem_flg=SEM_UNDO;//〃第二个参数是sembuf[]类型的,表示数组TOC\o"1-5"\h\z〃第三个参数表示第二个参数代表的数组的大小 | | |if(semop(sem_id,&sb,1)<0){ii perror("waitSemfailed"); i i iexit(1); j j jJ! !} ! ! !//V操作voidsigSem(intsem_id,intsem_num){iistructsembufsb; i!!।_!!!sb.sem_num—sem_num;sb.sem_op—1;sb.sem_flg—SEM_UNDO;〃第二个参数是sembuf[]类型的,表示数组〃第三个参数表示第二个参数代表的数组的大小 | | |TOC\o"1-5"\h\z| | if(semop(sem_id,&sb,1)<0){ I I II Iperror("sigSemfailed"); I I Iexit(1); । । ।Ji i} i i i〃打印进程运行结果 i i i| |voidprintTime() III{ ill〃打印时间 i i itime_tnow;| | structtm*timenow; 〃实例化 tm结构指针 | | || 工 time(&now); | | || | timenow=localtime(&now); | |||printf("执行时间:%s",asctime(timenow)); j jI IJintmain(intargc,char**argv)। । f ■ ।I shm_id=shmget(IPC_PRIVATE,MAX_BUFFER_SIZE,SHM_MODE);〃申请共享内存if(shm_id<0); ; perror("createsharedmemoryfailed"); ; ;exit(1);I structmy_buffer*shmptr;shmptr=shmat(shm_id,0,0);〃将申请的共享内存附加到申请通信的进程空间! ! if (shmptr == (void*)-1) ! !r। । j । ।। । I । ।| | perror("add buffer to usingprocessspacefailed!\n"); | |exit(1);J! !if((sem_id=semget(IPC_PRIVATE,3,SEM_MODE))<0) ] !{〃创建三个信号量,SEM_EMPTY,SEM_FULL和MUTEX! ! perror("createsemaphorefailed!\n"); ' 'I I exit(1); i i}j j if(semctl(sem_id,SEM_FULL,SETVAL,0)==-1) j j| | {〃将索引为0的信号量设置为0-->SEM_FULL | |! ! perror("semsetvalueerror!\n"); ! !| | exit(1);}if(semctl(sem_id,SEM_EMPTY,SETVAL,10)==-1){〃将索引为1的信号量设置为10-->SEM_EMPTYperror("semsetvalueerror!\n");| |exit(1);}if(semctl(sem_id,MUTEX,SETVAL,1)==-1){〃将索引为3的信号量设置为1-->MUTEXperror("semsetvalueerror!\n");exit(1);}shmptr->head=0;■ ■shmptr->tail=0;shmptr->is_empty=1;| | shmptr->num=0;: : inti;for(i=0;i<N_PRODUCER;i++){parent=fork();IIif(parent<0){! ! perror("theforkfailed");'' exit(1);}! ! elseif(parent==0){iI shmptr=shmat(shm_id,0,0);〃将申请的共享内存附加到申请通信的进程空间| | if(shmptr==(void*)-1){| | perror("addbuffertousingprocessspacefailed!\n");| | exit(1);}| | intcount=0;intj;for(j=0;j<N_WORKTIME;j++){waitSem(sem_id,SEM_EMPTY);; ; waitSem(sem_id,MUTEX);sleep(getrandom());printf(" \n);| | printf("我是第%d个生产者进程,PID =%d\n", i + 1, getpid());| | /*生产产品*/charc=getRandChar();//随机获取字母| | shmptr->str[shmptr->tail]=c;shmptr->tail=(shmptr->tail+ 1) % MAX_BUFFER_SIZE;shmptr->is_empty=0;//写入新产品! ! shmptr->num++;/*打印输出结果*/printTime();//程序运行时间| | intp;I | printf("缓冲区数据(%d个):",shmptr->num);〃打印缓冲区中ii的数据| | p=(shmptr->tail-1>=shmptr->head)?(shmptr->tail-1):I ](shmptr->tailT+MAX_BUFFER_SIZE); |for(p;!(shmptr->is_empty)&&p>=shmptr->head;p--){printf("%c",shmptr->str[p%MAX_BUFFER_SIZE]);}printf("\t生产者%d放入'%c'.\n",i+1,c);printf("n);fflush(stdout);sigSem(sem_id,MUTEX);sigSem(sem_id,SEM_FULL);}〃将共享段与进程之间解除连接shmdt(shmptr);exit(0);}}for(i=0;i<N_CONSUMER;i++){child=fork();if(child<0)//调用fork失败{perror("theforkfailed");exit(1);}elseif(child==0){intcount=0;shmptr=shmat(shm_id,0,0);〃将申请的共享内存附加到申请通信的进程空间| | if(shmptr==(void*)-1){i i perror("addbuffertousingprocessspacefailed!\n");j j exit(1);}intj;for(j=0;j<N_WORKTIME;j++){waitSem(sem_id,SEM_FULL);; ; waitSem(sem_id,MUTEX);sleep(get_random());| |printf(" \printf("我是第%d个消费者进程,PID=%d\n",i+1,getpid());/*消费数据*/I| charlt=shmptr->str[shmptr->head];shmptr->head=(shmptr->head+1)%MAX_BUFFER_SIZE;shmptr->is_empty=(shmptr->head==shmptr->tail);//' ' shmptr->num一一;/*打印输出结果*/! ! printTime();〃程序运行时间| | intp;| | printf("缓冲区数据(%d个):",shmptr->num);//打印缓冲区中! !的数据|| p=(shmptr->tail-1>=shmptr->head)?(shmptr->tail-1):II(shmptr->tail-1+MAX_BUFFER_SIZE);for(p;!(shmptr->is_empty)&&p>=shmptr->head;p--){printf("%c",shmptr->str[p%MAX_BUFFER_SIZE]);}| | printf("\t消费者%d取出'%c'.\n",i+1,It);jjprintf(" \n);fflush(stdout);sigSem(sem_id,MUTEX);sigSem(sem_id,SEM_EMPTY);i — —}〃将共享段与进程之间解除连接shmdt(shmptr);exit(0);}}〃主进程最后退出| |while(wait(0)!=-1);〃将共享段与进程之间解除连接shmdt(shmptr);〃对共享内存区执行控制操作| |shmctl(shm_id,IPC_RMID,0);//当cmd为IPC_RMID时,删除该共享段! !shmctl(sem_id,IPC_RMID,0);printf("主进程运行结束!\n");| | fflush(stdout);i i exit(0);! ! return0;}

实验二:#include<sys/types.h>#include<unistd.h>#include<stdlib.h>#include<stdio.h>#include<pthread.h>#include<semaphore.h>#include<time.h>#define〃哲学家数量#define#define#define#defineLEFT(i)RIGHT(i)(i+N-1)%N〃左手边哲学家编号(i+1)%N 〃右手边哲家编号#define#define#defineHUNGRYTHINKINGEATING//饥饿//思考//吃饭#defineUSECOND1000000 //1秒对应的微秒数pthread_mutex_tmutex;//互斥量intstate[N];〃记录每个哲学家状态〃每个哲学家的思考时间,吃饭时间,思考开始时间,吃饭开始时间clocktthinking_time[N],eating_time[N],start_eating_time[N],start_thinking_time[N];〃线程函数void*thread_function(void*arg);intmain(){pthread_mutex_init(&mutex,NULL);pthread_ta,b,c,d,e;〃为每一个哲学家开启一个线程,传递哲学家编号pthread_create(&a,NULL,thread_function,"0");pthread_create(&b,NULL,thread_function,"1");pthread_create(&c,NULL,thread_function,"2");pthread_create(&d,NULL,thread_function,"3");pthread_create(&e,NULL,thread_function,"4");〃初始化随机数种子srand((unsignedint)(time(NULL)));iiwhile(1){TOC\o"1-5"\h\zii i। । i::, :}}void*thread_function(void*arg){char*a=(char*)arg;intnum=a[0]-'0';〃根据传递参数获取哲学家编号intrand_time;! !while⑴{〃关键代码加锁pthread_mutex_lock(&mutex);〃如果该哲学家处于饥饿并且左右两位哲学家都没有在吃饭就拿起叉子吃饭if(state[num]==HUNGRY&&state[LEFT(num)]!=EATING&&| |state[RIGHT(num)]!=EATING){| | 'state[num]=EATING;start_eating_time[num]=clock();//记录开始吃饭时间eating_time[num]=(rand()%5+5)*U_SECOND;〃随机生成吃饭时间〃输出状态printf("state:%d%d%d%d%d\n",state[0],state[1],state[2],state[3],state[4]);//printf("%diseating'n",num);}II elseif(state[num]==EATING){〃吃饭时间已到,开始思考if(clock()-start_eating_time[num]>=eating_time[num])//{I | state[num]=THINKING;! ! //printf("%disthinking'n",num);| |printf("state:%d%d%d%d%d\n",state[0],state[l],state[2],state[3],stat| |e[4]);start_thinking_time[num]=clock();/记录开始思考时间thinking_time[num]=(rand()%10+10)*U_S

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论