欢迎来到天天文库
浏览记录
ID:30881047
大小:76.62 KB
页数:4页
时间:2019-01-03
《实验五线程间的互斥与同步》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
实验五线程间的互斥与同步姓名:王睿慕学号:14072233完成口期:2016年12月11口一、实验目的理解POSIX线程(Pthread)互斥锁和POSIX信号量机制,学习它们的使用方法;编写程序,实现多个POSIX线程的同步控制。二、实验内容【任务5.1】创建4个POSIX线程。其中2个线程(A和B}分别从2个数据文件(datal.txt和data2.txt)读取10个整数.线程A和B把从文件中读取的整数逐一放入一个缓冲池。缓冲池由n个缓冲区构成(n=5,并可以方便地调整为其他值),每个缓冲区可以存放一个整数。另外2个线程,C和D,每次从缓冲池读取1个数据,分别共计读10次。线程C、D,每读出2个数据,分别求出两个数的和或乘积,并打卬输出。提示:(1)在创建4个线程当中,A和B是生产者,负责从文件读取数据到公共的缓冲区,C和D是消费者,从缓冲区读収数据然后作不同的计算(加和乘运算)。使用互斥锁和信号量控制这些线程的同步。不限制线程C和D从缓冲区得到的数据来自哪个文件。(2)在生产者线程中,确保从文件读出数据以后,再去“生产”。三、实验要求按照要求编写程序,放在相应的目录屮,编译成功后执行,并按照要求分析执行结果,并写出实验报告。四、实验设计(1)功能设计从dataO.txt和datal.txt轮流读入总计十个数,每读取两个数都可以通过键盘控制(输入1或者2)对这两个数选择进行加法操作或者乘法操作。(2)数据结构使用二维数组作为公共缓冲区(经老师mtbuffer[2]:指正它的实质其实是栈)voidinitial():voidreadl():voidread20:voidcalculate0:除了主函数main以外设定了四个函数,readl函数和read2函数分别用于从dataO.txt和datal.txt读入10个数,calculate函数根据用户的反馈来确定进行加法操作还是乘法操作oInitial函数用于对信号量进行初始化。主函数里依次调用这些函数 intaain(void)mtbuffer[NUM][2]:pthread.ttl,t2,t3:〃定义线程标识符initial0:pthread_create(&t1,NULL,(void»)readl,NULL)://创建线程甘淀线程运行因旷pthread^create(&t2,NULL,(void*)read2,NULL):pthread_create(&t3,NULL^(void*)calculate,NULL):pthread_join(t1,NULL):/,等诗线程运亍结束⑶程序框图t2t3*&&:&」⑷参数说明整型数组intbuffer[NUM][2];用来存放线程从文件所读入的10个数;数组索引intsize=O;指向数组的顶部之后在存収数据的时候值会发生变化;三个信号量sem_tseml,sem2,sem3;整型变量intget_num;由键盘读入,用来控制线程进行加运算或者乘运算。⑸源代码#include#include#inelude#defineNUM200intbuffer[NUM][2];〃公共缓冲区intsize=0;〃初始化数组索引semjsemlzsem2rsem3;〃定义3个信号量voidinitial();voidread1();voidread20;voidcalculateQ; intmain(void)//intbuffer[NUM][2];pthread.ttl,t2,t3;〃定义线程标识符initialO;pthread_create(&tl,NULL,(void*)readl,NULL);//创建线程并调用自定义函数pthread_create(&t2.NULL,(void*)read2,NULL);pthread_create(&t3fNULU(void*)calculate,NULL);pthreadjoin(tl,NULL);}voidinitial(){sem_init(&seml,0,l);〃初始化信号量semjnit(&sem2Q0);sem」nit(&sem3,0r0);}voidreadl(){〃负责从文件读取数据FILE*fp二fopen("data0.txt","r");〃以只读方式打开文件dataOwhile(!feof(fp)){sem_wait(&seml);〃减少信号呈semiif(!fscanf(fp/%d%dM/&buffer[size][O]/&buffer(size](l]))return;size++;〃读两个数到公共缓冲区sem_post(&sem2);〃増加信号量sem2}fclose(fp);〃关闭文件}voidread2(){FILE*fp=fopen(,,datal.txtn/nrM);while(!feof(fp)){sem_wait(&sem2);〃减少信号量sem2if(!fscanf(fp/%d%d&buffer[size][O]/&buffer[size][l]))return;size++;〃读两个数到公共缓冲区sem_post(8isem3);〃增加信号呈sem3}fclose(fp);}voidcalculateot//线程运行函数负责选择进行加运算或者乘运算intget_num;while(l){讦(size==O){return;} size—;printf(MPlus(enter1)orMultiply(enter2)?rT);scanf(n%d",&get_num);if(get_num==l)printf(,,Plus:%d+%d=%d ,buffer[size][O],buffer[size][l],buffer[size][O]+buffer[size][l]);//从公共缓冲区取数并逬行加运算elseprin廿("Multiply:%d*%d=%d buffer[size][O]/buffer[size][l]rbuffer(size][O]*buffer[size][l]);//从公共缓冲区取数并进行乘运算sem_post(&seml);/澹加信号呈semi}}五、实验测试结果以及分析14C72233@blackbamboo:^/lab5$gcctest・c-pthre&d-otest14C722330blackbamboo:^/lab5$•/testPlus(enter1)orMultiply(enter2)?1Plus:1+2=3Plus(enter1)orMultiply(enter2)?2Multiply:3*4«12Plus(enter1)orMultiply(enter2)?2Multiply:5*6=30Plus(enter1)orMultiply(enter2)?1Plus:7+8-1514G72233@blackbdmboo:~/“b5$■虽然能满足题目在操作上的要求但是只建立了三个线程并且没有运用到互斥锁,而且在线程运行读取文件的函数里没有进行判断是否出错(没有读到文件或者文件内容不符合操作规范)。六、收获及体会这个实验是我独立完成的(参考了网上的程序自己进行改动和分析),因为我自身的水平和一些其他因素仓促地完成了这个实验导致有很多地方值得完善。但是多多少少还是学到了一些东西,了解了UNIX信号量机制,掌握了编写Linux环境下利用信号量实现进程控制方法及相关系统调用的使用方法。在编译的时候也出现过一些问题,在读取文件的时候出现过错误(后来发现是因为文件内容导致的),分析原因后把文件内容改规范了,现在想来,当时应该加一个判断错误的部分进去的。我在设置了三个信号量,但是在程序实际运行之后发现实际起到作用的好像只有两个。因为电脑没有办法安装虚拟机在老师帮助下成功地使用了putty和远程同步的软件完成了实验,这也算一个额外的收获吧。
此文档下载收益归作者所有
举报原因
联系方式
详细说明
内容无法转码请点击此处