实现读者写者28ReaderWriter+Problem29问题3Word格式文档下载.docx
- 文档编号:22680352
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:29
- 大小:180.62KB
实现读者写者28ReaderWriter+Problem29问题3Word格式文档下载.docx
《实现读者写者28ReaderWriter+Problem29问题3Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《实现读者写者28ReaderWriter+Problem29问题3Word格式文档下载.docx(29页珍藏版)》请在冰豆网上搜索。
使多CPU系统更加有效;
改善程序结构。
多线程编程是一个很有意思也很有用的技术,使用多线程技术的网络蚂蚁是目前最常用的下载工具之一,使用多线程技术的grep比单线程的grep要快上几倍,类似的例子还有很多。
和进程相比,线程的最大优点之一是数据的共享性,各个进程共享父进程处沿袭的数据段,可以方便的获得、修改数据。
但这也给多线程编程带来了许多问题。
我们必须当心有多个不同的进程访问相同的变量。
许多函数是不可重入的,即同时不能运行一个函数的多个拷贝(除非使用不同的数据段)。
在函数中声明的静态变量常常带来问题,函数的返回值也会有问题。
因为如果返回的是函数内部静态声明的空间的地址,则在一个线程调用该函数得到地址后使用该地址指向的数据时,别的线程可能调用此函数并修改了这一段数据。
在进程中共享的变量必须用关键字volatile来定义,这是为了防止编译器在优化时(如gcc中使用-OX参数)改变它们的使用方式。
为了保护变量,我们必须使用信号量、互斥等方法来保证我们对变量的正确使用。
2.2信号量
信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。
当公共资源增加时,调用函数sem_post()增加信号量。
只有当信号量值大于0时,才能使用公共资源,使用后,函数sem_wait()减少信号量。
函数sem_wait()和函数pthread_mutex_lock()起同样的作用。
下面我们逐个介绍和信号量有关的一些函数,它们都在头文件/usr/include/semaphore.h中定义。
信号量的数据类型为结构sem_t,它本质上是一个长整型的数。
函数sem_init()用来初始化一个信号量。
它的原型为:
externintsem_init__P((sem_t*__sem,int__pshared,unsignedint__value));
sem为指向信号量结构的一个指针;
pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;
value给出了信号量的初始值。
表1关于信号量的函数和功能
函数名
功能
sem_post(sem_t*sem)
用来增加信号量的值
sem_wait(sem_t*sem)
被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少
sem_trywait(sem_t*sem)
是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一
sem_destroy(sem_t*sem)
用来释放信号量sem
3总体设计
3.1设计思想
本设计要实现的要求是:
读者-写者问题的读写操作限制:
(1)写-写互斥,即不能有两个写者同时进行写操作
(2)读-写互斥,即不能同时有一个读者在读,同时却有一个写者在写
(3)读-读允许,即可以有二个以上的读者同时读
另外本文使用读者优先的方法进行设计。
首先给出PV操作的伪代码:
Shareddata
semaphoremutex;
//用于保护共享变量readcount,实现互斥访问
semaphorewrt;
//用于互斥访问内存
Initially
mutex=1,wrt=1,readcount=0
writerprocess:
begin
do{
wait(wrt);
//给内存访问加锁
writing;
//开始读
signal(wrt);
//解锁内存的访问
}while
(1);
end
Readerprocess:
do{
wait(mutex);
//保护共享变量readcount
readcount++;
if(readcount==1)//如果是第一个读者
wait(rt);
//给内存访问加锁
signal(mutex);
//解除保护
reading;
//保护共享变量readcount
readcount--;
if(readcount==0)//若是最后一个读者
signal(wrt);
}while
(1);
3.2数据结构和模块说明
3.2.1主函数
图1主函数流程图
3.2.2写者线程函数
图2写者线程函数流程图
3.2.3读者线程函数
图3读者线程函数流程图
3.3开发工具的选择
操作系统:
linux
内存:
1G
工具:
g++,vim,geany
4详细设计
4.1源程序
/*
reader-writerProblem
auther:
zhengfeirj0315
Modole:
semaphoremutex,wrt;
if(readcount==1)
if(readcount==0)
*
*/
#include<
iomanip>
unistd.h>
stdio.h>
pthread.h>
math.h>
time.h>
stdlib.h>
iostream>
fstream>
string>
semaphore.h>
#definereaderNum5
#definewriterNum7
#defineBUFFERSIZE20
usingnamespacestd;
intwriteRoom[writerNum];
//tostorewhichbuffereverywriterarewriting
intreadRoom[readerNum];
//tostorewhichbuffereveryreaderarereading
intbuffer[BUFFERSIZE];
//thebuffer
stringbufferOwn[BUFFERSIZE];
//whousethebuffer
intreadcount=0;
intreadp=0;
intwriterp=0;
intcontent_id=0;
//thecontentidofthebuffer
sem_tmutex;
sem_twrt;
time_tnow;
ofstreamfout("
out.txt"
);
stringint2str(intn){
chartemp[8];
sprintf(temp,"
%d"
n);
return(string)temp;
}
voidshowbuffer(){
intwidth=4;
for(inti=0;
i<
BUFFERSIZE;
i++){
bufferOwn[i]="
"
;
fout<
<
setw(width)<
buffer[i];
cout<
}
fout<
endl;
cout<
readerNum;
if(readRoom[i]!
=-1)
bufferOwn[readRoom[i]]+="
r"
+int2str(i);
writerNum;
if(writeRoom[i]!
bufferOwn[writeRoom[i]]+="
w"
bufferOwn[i];
stringgettime(){
time(&
now);
stringt=ctime(&
returnt;
voidwriting(intn){
writeRoom[n]=rand()%BUFFERSIZE;
//setthewriteplacerandomly
writerp=writeRoom[n];
//thecurrentwriteplace
buffer[writerp]=content_id++;
//thewritingcontent,thecontentisrecognisebyaseriesofidwhichwillincreaseas1,2,3,4...
\nwriter"
n<
starttowritebuffer"
writerp<
on"
gettime();
showbuffer();
sleep(rand()%2+1);
finishwritingbuffer"
writeRoom[n]=-1;
voidreading(intn){
sem_wait(&
mutex);
readRoom[n]=rand()%BUFFERSIZE;
\nreader"
starttoreadbuffer"
readRoom[n]<
sem_post(&
finishreadingbuffer"
\nthereis"
readcount-1<
readersarestillreading"
readRoom[n]=-1;
void*writer_thread(void*wid){
while
(1){
/*wait(wrt);
sem_wait(&
wrt);
/*writing;
writing((int)wid);
/*signal(wrt);
sem_post(&
/*sleepawhileandthenwriteagain*/
sleep(rand()%5+1);
void*reader_thread(void*rid){
/*wait(mutex);
/*wait(wrt);
sem_wait(&
/*signal(mutex);
/*addemptybottletobuffer;
reading((int)rid);
/*signal(wrt);
sem_post(&
/*signal(mutex);
*/
/*sleepawhileandthenreadagain*/
intmain(intargc,char*argv[]){
/*init*/
pthread_treader[readerNum],writer[writerNum];
sem_init(&
wrt,0,1);
mutex,0,1);
buffer[i]=-1;
readRoom[i]=-1;
writeRoom[i]=-1;
/*createthreads*/
pthread_create(&
reader[i],NULL,reader_thread,(void*)i);
writer[i],NULL,writer_thread,(void*)i);
sleep(40);
fout.close();
exit(0);
return0;
5运行结果与运行情况
在本程序的实现过程中,使用了vim编辑器。
下面是我的截图:
图4使用编辑器编辑
图5使用编辑器编辑
图6程序执行结果
由于执行结果很长,不好截图表示,故列出如下:
reader0starttoreadbuffer3onTueJun2300:
34:
522009
-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1
r0
reader1starttoreadbuffer17onTueJun2300:
r0r1
reader2starttoreadbuffer13onTueJun2300:
r0r2r1
reader3starttoreadbuffer6onTueJun2300:
r0r3r2r1
reader4starttoreadbuffer9onTueJun2300:
r0r3r4r2r1
reader0finishreadingbuffer3onTueJun2300:
532009
thereis4readersarestillreading
r3r4r2r1
reader3finishreadingbuffer6onTueJun2300:
thereis3readersarestillreading
r4r2r1
reader1finishreadingbuffer17onTueJun2300:
542009
thereis2readersarestillreading
r4r2
reader2finishreadingbuffer13onTueJun2300:
thereis1readersarestillreading
r4
reader4finishreadingbuffer9onTueJun2300:
thereis0readersarestillreading
writer0starttowritebuffer6onTueJun2300:
-1-1-1-1-1-10-1-1-1-1-1-1-1-1-1-1-1-1-1
w0
writer0finishwritingbuffer6onTueJun2300:
552009
writer1starttowritebuffer12onTueJun2300:
-1-1-1-1-1-10-1-1-1-1-11-1-1-1-1-1-1-1
w1
writer1finishwritingbuffer12onTueJun2300:
562009
writer2starttowritebuffer8onTueJun2300:
-1-1-1-1-1-10-12-1-1-11-1-1-1-1-1-1-1
w2
writer2finishwritingbuffer8onTueJun2300:
582009
writer3starttowritebuffer2onTueJun2300:
-1-13-1-1-10-12-1-1-11-1-1-1-1-1-1-1
w3
writer3finishwritingbuffer2onTueJun2300:
592009
writer4starttowritebuffer3onTueJun2300:
-1-134-1-10-12-1-1-11-1-1-1-1-1-
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实现 读者 28 ReaderWriter Problem29 问题