读者 写者问题C 源代码
读者-写者问题(Reader-Writer Problem)

学号:课程设计题目用多线程同步方法解决读者-写者问题(Reader-Writer Problem)学院计算机科学与技术学院专业软件工程班级姓名指导教师2010 年 6 月日目录目录 (1)课程设计任务书 (1)正文 (2)1.设计目的与要求 (2)1.1设计目的 (2)1.2设计要求 (2)2.设计思想及系统平台 (2)2.1设计思想 (2)2.2系统平台及使用语言 (3)3.详细算法描述 (3)4.源程序清单 (6)5.运行结果与运行情况 (9)6.调试过程 (11)7.总结 (12)本科生课程设计成绩评定表 (13)课程设计任务书学生姓名:专业班级:指导教师:工作单位:计算机科学与技术学院题目: 用多线程同步方法解决读者-写者问题(Reader-Writer Problem)初始条件:1.操作系统:Linux2.程序设计语言:C语言3.设有20个连续的存储单元,写入/读出的数据项按增序设定为1-20这20个字符。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.技术要求:1)为每个读者/写者产生一个线程,设计正确的同步算法2)每个读者/写者对该存储区进行操作后,即时显示该存储区的全部内容、当前指针位置和读者/写者线程的自定义标识符。
3)读者应有3个以上,写者应有有两个以上。
4)多个读者/写者之间须共享对存储区进行操作的函数代码。
2.设计说明书内容要求:1)设计题目与要求2)总的设计思想及系统平台、语言、工具等。
3)数据结构与模块说明(功能与流程图)4)给出用户名、源程序名、目标程序名和源程序及其运行结果。
(要注明存储各个程序及其运行结果的主机IP地址和目录。
)5)运行结果与运行情况(提示: (1)连续存储区可用数组实现。
(2)编译命令可用:cc -lpthread -o 目标文件名源文件名(3)多线程编程方法参见附件。
)3. 调试报告:1) 调试记录2)自我评析和总结上机时间安排:18周一~ 五08:0 -12:00指导教师签名:年月日系主任(或责任教师)签名:年月日正文1.设计目的与要求1.1设计目的通过研究Linux的线程机制和信号量实现读者写者问题(Reader-Writer Problem )的并发控制。
操作系统读者写者问题 源代码

在linux环境下运行!#include<sys/types.h>#include<sys/ipc.h>#include<sys/sem.h>#include<errno.h>#include<stdlib.h>#include<stdio.h>#include<unistd.h>union semun{int val;struct semid_ds *buf;unsigned short *array;struct seminfo *_buf;};int *readcount;static int shmid,semid,s;int main(){key_t semkey,shmkey,skey;union semun arg;if((semkey=ftok(".",0x16))==-1) printf("error1\n") ;if((skey=ftok(".",0x36))==-1) printf("error3\n");if((shmid=shmget(IPC_PRIVATE,1024,0600|IPC_CREAT))==-1) printf("error4\n"); if((shmat(shmid,NULL,0))==-1) printf("error!\n");readcount=(int *)shmat(shmid,NULL,0);semid=semget(semkey,1,0600|IPC_CREAT);s=semget(skey,1,0600|IPC_CREAT);arg.val=1;semctl(semid,0,SETVAL,arg);semctl(shmid,0,SETVAL,arg);semctl(s,0,SETVAL,arg);int initsem(int key){return(semget(key,1,0600|IPC_CREAT|IPC_EXCL));}int P(int semidd,int semnun){struct sembuf sops={semnun,-1,SEM_UNDO};return(semop(semidd,&sops,1));}int V(int semidd,int semnun){struct sembuf sops={semnun,+1,SEM_UNDO};return(semop(semidd,&sops,1));}void writer(int k){while(k>0){P(s,0);P(semid,0);if(*readcount==0) P(shmid,0);(*readcount)++;V(semid,0);V(s,0);printf("XIE jing c\n");P(semid,0);(*readcount)--;;if((*readcount)==0) V(shmid,0); V(semid,0);k--;}}void reader(int j){while(j>0){P(s,0);P(shmid,0);printf("DU jing c\n");V(shmid,0);V(s,0);j--;}}writer(5);reader(6);return 0;}。
读者——写者 代码

Sleep(m_persist);
//退出线程
printf("Reader thread %d finished reading file.\n",m_serial);
//等待互斥信号,保证对ReadCount的访问,修改互斥
wait_for_mutex=WaitForSingleObject(h_Mutex,-1);
}
ReleaseMutex(h_Mutex); //释放互斥信号
}
//////////////////////////////////////////////////////////////
//P:写者线程信息
};
///////////////////////////////////////////////////////////////////////////
// 读者优先---读者线程
//P:读者线程信息
void RP_ReaderThread(void *p)
ifstream inFile;
inFile.open (file);
printf("Reader Priority:\n\n");
while(inFile)
{
//读入每一个读者,写者的信息
char entity; //线程类别(判断是读者还是写者线程)
double delay; //线程延迟时间
double persist; //线程读写操作时间
inFile>>thread_info[n_thread].serial;
inFile>>thread_info[n_thread].entity;
C图书管理系统源代码

C图书管理系统源代码Newly compiled on November 23, 2020图书管理系统系统功能:1.借书:根据借书人提出的图书编号(id)查询该图书,如果该图书现存量(store)不为0,则提示输入借阅者的学号(num),为借书人办理借书手续,提示用户该书已被借出。
2.归书:根据借书人的学号查询该读者的信息,若有该读者,则提示输入所借书籍的编号(id),为该读者办理还书手续,提示该书已还。
3.书籍管理:弹出书籍管理界面,输入所要执行操作的号码:(1)增加书籍:弹出注册新书的窗口,按照提示输入所增加书籍的信息,最后,提示用户该书已被注册。
(2)删除书籍:弹出删除书籍的窗口,输入所要删除书籍的编号(id),输出该书的信息,确认是否删除该书,1为删除,0为放弃。
(3)修改书籍:弹出修改书籍的窗口,输入所要修改书籍的编号(id),输出该书的信息,确认是否修改该书,1为修改,0为放弃。
之后按照提示重新输入书籍的信息。
4.读者管理:弹出读者管理界面,输入所要执行操作的号码:(1)增加读者:弹出注册读者的窗口,按照提示输入所增加读者的信息,最后,提示用户该读者已被注册。
(2)删除书籍:弹出删除读者的窗口,输入所要删除读者的学号(num),输出该读者的信息,确认是否删除该读者,1为删除,0为放弃。
(3)修改书籍:弹出修改读者的窗口,输入所要修改读者的学号(num),输出该读者的信息,确认是否修改该读者,1为修改,0为放弃。
之后按照提示重新输入读者的信息。
5.搜索:此搜索包括两方面的搜索,书籍搜索以及读者搜索,弹出搜索的窗口,按照提示输入所要搜索的内容,1为书籍搜索,2为读者搜索:(1)搜索书籍:弹出搜索书籍的窗口,按照提示输入所要搜索的方式,包括按<1>书名搜索,<2>书号搜索,<3>作者搜索,<4>出版社搜索,<5>出版时间搜索;根据所选方式输入相应的内容,若是该书籍存在,则输出该书籍的信息,否则,返回主界面。
OS:读者写者问题(写者优先+LINUX+多线程+互斥量+代码)

OS:读者写者问题(写者优先+LINUX+多线程+互斥量+代码)⼀. 引⼦最近想⾃⼰写个简单的 WEB SERVER ,为了先练练⼿,熟悉下在LINUX系统使⽤基本的进程、线程、互斥等,就拿以前学过的 OS 问题开开⼑啦。
记得当年学读者写者问题,尤其是写者优先的时候,那是真⼼纠结啊。
刚才还觉得理解了,过⼀会⼉⼜糊涂了。
现在重新再看,还是容易纠结。
没办法,⽤得少。
我把读者优先和写者优先都实现了⼀下。
选择性重看了⼩部分《unix⾼程》使⽤了多线程+互斥量实现。
⼆. 互斥量与信号量互斥量如其名,同⼀时间只能被⼀个线程占有,实现线程间对某种数据结构的互斥访问。
试图对⼀个已经加锁的互斥量加锁,会导致线程阻塞。
允许多个线程对同⼀个互斥量加锁。
当对互斥量解锁时,阻塞在该互斥量上的线程会被唤醒,它们竞争对该互斥量加锁,加锁成功的线程将停⽌阻塞,剩余的加锁失败于是继续阻塞。
注意到,谁将竞争成功是⽆法预料的,这⼀点就类似于弱信号量。
(强信号量把阻塞在信号量上的进程按时间排队,先进先出)互斥量区别于信号量的地⽅在于,互斥量只有两种状态,锁定和⾮锁定。
它不像信号量那样可以赋值,甚⾄可以是负值。
共性⽅⾯,我所体会到的就⼀句话,都是⽤来实现互斥的。
⾄于其它区别或联系,⽤不上,不作研究。
三. 读者优先只要有⼀个读者正在读,那么后续的读者都能⽴即读,不管有多少写者在等待。
可能导致写者饥饿。
1. 读者1) 写者写时,不可读2) 有别的读者正在读,可读2. 写者1) 有读者正在读,不可写2) 有写者正在写,不可写3) ⽆读者正在读,⽆写者正在写,可写四. 写者优先当新的写者希望写时,不允许该写者后续的读者访问数据区,但必须保证之前的读者读完。
1. 读者特点1) 有写者正在写或者等待写,须等到没有写者才能读2) 没有写者,可以读2. 写者特点1) 写者与写者互斥。
当其它写者正在写时,其它写者不能写。
2) 写者与读者互斥。
之前只有读者在读,当写者出现时,必须等到之前的读者都读完才能写。
在linux下实现读者写者问题源代码

在linux下实现读者写者问题源代码读者写者问题是计算机科学中的一个经典同步问题,用于描述多个读者和写者对共享资源的访问。
在这个问题中,多个读者可以同时读取共享资源,但是写者在写入共享资源时必须独占访问。
在Linux下,我们可以使用线程和互斥锁来实现读者写者问题。
下面是一个简单的源代码示例:```c#include <stdio.h>#include <stdlib.h>#include <pthread.h>#define READERS_COUNT 5#define WRITERS_COUNT 2pthread_mutex_t mutex;pthread_cond_t cond_reader, cond_writer;int readers = 0;int writers = 0;void *reader(void *arg) {int id = *(int *)arg;while (1) {pthread_mutex_lock(&mutex);while (writers > 0) {pthread_cond_wait(&cond_reader, &mutex); }readers++;pthread_mutex_unlock(&mutex);// 读取共享资源printf("Reader %d is reading\n", id);pthread_mutex_lock(&mutex);readers--;if (readers == 0) {pthread_cond_signal(&cond_writer);}pthread_mutex_unlock(&mutex);}pthread_exit(NULL);}void *writer(void *arg) {int id = *(int *)arg;while (1) {pthread_mutex_lock(&mutex);while (readers > 0 || writers > 0) {pthread_cond_wait(&cond_writer, &mutex); }writers++;pthread_mutex_unlock(&mutex);// 写入共享资源printf("Writer %d is writing\n", id);pthread_mutex_lock(&mutex);writers--;pthread_cond_signal(&cond_writer);pthread_cond_broadcast(&cond_reader);pthread_mutex_unlock(&mutex);}pthread_exit(NULL);}int main() {pthread_t readers[READERS_COUNT];pthread_t writers[WRITERS_COUNT];int reader_ids[READERS_COUNT];int writer_ids[WRITERS_COUNT];pthread_mutex_init(&mutex, NULL);pthread_cond_init(&cond_reader, NULL);pthread_cond_init(&cond_writer, NULL);// 创建读者线程for (int i = 0; i < READERS_COUNT; i++) {reader_ids[i] = i + 1;pthread_create(&readers[i], NULL, reader, &reader_ids[i]); }// 创建写者线程for (int i = 0; i < WRITERS_COUNT; i++) {writer_ids[i] = i + 1;pthread_create(&writers[i], NULL, writer, &writer_ids[i]); }// 等待线程结束for (int i = 0; i < READERS_COUNT; i++) {pthread_join(readers[i], NULL);}for (int i = 0; i < WRITERS_COUNT; i++) {pthread_join(writers[i], NULL);}pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond_reader);pthread_cond_destroy(&cond_writer);return 0;}```在这个源代码中,我们使用了互斥锁(`pthread_mutex_t`)和条件变量(`pthread_cond_t`)来实现读者写者问题的同步。
读者写者

char thread_name[3]; //线程名
unsigned int require_moment; //请求操作时刻
unsigned int persist_time; //操作持续时间
CRITICAL_SECTION CS_DATA; //用于保护文件的临界区变量
HANDLE h_mutex_read_count=CreateMutex(NULL,FALSE,"mutex_read_count");
//读者计数器互斥体
HANDLE h_mutex_write_count=CreateMutex(NULL,FALSE,"mutex_write_count");
}
WaitForMultipleObjects(MAX_THREAD,h_thread,TRUE,-1); //等待所有线程结束
printf("\n");
}
//无优先时的读者线程
void FIFO_reader_thread(void *data){
char thread_name[3];
}TEST_INFO;
TEST_INFO test_data[MAX_THREAD]={ //测试数据表
{"r1",0,15},
{"r2",1, 15},
{"w1",3,3},
{"r3",4, 2},
//写者计数器互斥体
HANDLE h_mutex_reader_wait=CreateMutex(NULL,FALSE,"mutex_reader_wait");
基于C++的读者与写者问题read—writeproblem的实现(一)

基于C++的读者与写者问题read—writeproblem的实现(一)基于C++的读者与写者问题的实现 11.设计题目与要求 12.总的设计思想及系统平台、语言、工具等 12.1设计思想 12.2系统平台,语言,工具 43.数据结构与模块说明(功能与流程图) 43.1功能实现 43.2流程图 64.源程序 74.1.ReaderAndWriter.CPP //具体的实现 74.2.thread.dat//辅助的文件,但是必不可以少 155.运行结果与运行情况 156.调试记录 177.自我评析和总结 18基于C++的读者与写者问题read—writeproblem的实现1.设计题目与要求读者写者问题(read—writeproblem)是一个经典的并发程序设计问题。
有两组并发进程:读者和写者,共享一个问题F,要求:(1)允许多个读者可同时对之执行读*作;(2)只允许一个写者往文件中写信息;(3)任一写者在完成写*作之前不允许其他读者或者写者工作;(4)写者执行写*作前,应让已有的写者和读者全部退出。
2.总的设计思想及系统平台、语言、工具等2.1设计思想根据题目要求,首先分析了以下4种可能发生的情况:第1种情况:读者的优先权比写者高,而且,不用调配。
所有读者的优先权都比写者的优先权高,而且,不用调配。
一个读者需要等待的唯一情况是,一个写者已经占用了文件。
一个写者可以取得文件的条件是,没有一个读者处在等待状态或正在读文件。
允许读者们结盟,以便能长期占用文件,而禁止写者的写。
第2种情况:在一个读者已经占有了文件的时候,全体读者的优先权才比写者高。
在没有任何一个读者在读文件时,读者的优先权和写者的优先权相同。
相反,如果有一个读者正在读文件,则其余的各读者都可以读文件,而不管有多少写者处在等待状态。
所有读者都有权结盟,以便垄断文件。
第3种情况:写者的优先权比读者的优先权高。
在一个写者提出要访问文件时,就必须使其尽可能的得到文件,而且不用调配。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
读者——写者问题 C++程序 (原创作品)
演示效果图:
程序完整代码: #include <windows.h> #include <iostream.h> #include <fstream.h> #include <string.h> #include<string> #include<stdlib.h>//包含清屏头文件 //全局变量 int empty=1;//信号量 int wrIn=1;//信号量 int max; int temp[30]; int *wait,*next; int count=0;//记录已经完成操作的线程数 int waitSemapore; int type;//类型记录 int writc=1; int readc=1;
outfile.close(); count++; //wrIn++;//V 操作改变信号量 //empty++;//V 操作改变信号量 }//////////////////////////////////////////////////////////////写者函数结尾
void codeIn()///////////////////////////////////////////////////////////////// 输入界面 { int ru; cout<<"请输入你要创建多少个线程:"<<endl; cin>>max; for(int i=0;i<max;i++) { cout<<"你所要创建的第"<<i+1<<"个线程类型为:1.读者 2.写者"<<endl; cin>>ru;/////////////// if(ru==1||ru==2) temp[i]=ru; else cout<<"输入有误!请重新输入"<<endl;/////////////判断错误 if(i==max-1)//录入最后一个线程类型操作 { //system("cls");//清屏 HANDLE hOut; hOut = GetStdHandle(STD_OUTPUT_HANDLE); //设置输出字体颜色 red SetConsoleTextAttribute(hOut, FOREGROUND_RED | FOREGROUND_INTENSITY); cout<<endl<<"输入完毕!"<<endl; hOut = GetStdHandle(STD_OUTPUT_HANDLE); //设置输出字体背景 SetConsoleTextAttribute(hOut, BACKGROUND_GREEN | BACKGROUND_INTENSITY); for//////////////////输出录入结果 {cout<<"线程"<<j+1<<"为:"; if(temp[j]==1)cout<<"读者"<<endl; else cout<<"写者"<<endl; }///////////////////////////////输出录入结果 cout<<"下面将进行动态演示:"<<endl<<endl;
void reader()/////////////////////////////////////////////////////读者函数开始 { empty--;//P 操作改变信号量 cout<<"读者获得资源"<<"("; SYSTEMTIME sys; GetLocalTime(&sys);//输出系统时间 cout<<" 系 统 时 间 : "<<sys.wHour<<":"<<sys.wMinute<<":"<<sys.wSecond<<":"<<sys.wMilliseconds<<")"< <endl; cout<<endl<<"*"<<"读者正在进行读操作..."<<endl; //empty++;//信号量 count++; }/////////////////////////////////////////////////////////读者函数结尾
system("pause"); cout<<endl; }//录入最后一个线程类型操作 }//录入界面结束} }/////////////////////////////////////////////////////////codeIn()
int main()/////////////////////////////////////////////////主函数 { codeIn();//录入界面 wait=&temp[0]; while(wait<&temp[max]&&count<max) { waitSemapore=1; next=wait; while(*next==1||*next==2)//线程调用算法 { if(*next==1)//reader {if(empty==1||(empty==0&&wrIn==1&&*wait!=2))//体现写者优先 {reader();//调用读者函数 type=1;} else {cout<<"["<<"读者此时正在等待资源"<<"]"<<endl; //Sleep(5000);//////////////////////////////////////////////////////////// ////////////////////////////////sleep() if(waitSemapore==1) {wait=next;//////////this reader is waiting,locate it. waitSemapore--; } } } else//writer { if(empty==1) {writer();//调用写者函数 type=2;} else { cout<<"["<<"写者此时正在等待资源"<<"]"<<endl;
//Sleep(5000);//////////////////////////////////////////////////////////////// /////////////////////////////sleep() if(waitSemapore==1)///////////this writer is waiting,find it's location. {wait=next; waitSemapore--; } } }//writer is end next++; }//1while() if(type==1) {cout<<"~"<<"读者"<<readc<<"读完毕,释放资源"<<endl; readc++; empty++;//读者用的,但是为了在输出时演示出运行状态,不得不将其放在此处 Sleep(3000);////////////////////////////////////////////////////////////////// ///////////////////////////sleep() cout<<endl; } else if(type==2) { cout<<"~"<<"写者"<<writc<<"写完毕,释放资源" << endl; writc++; wrIn++;//V 操作改变信号量,写者用,但是为了在输出时演示出运行状态,不得不将其放 在此处 empty++;//V 操作改变信号量,写者用,但是为了在输出时演示出运行状态,不得不将其放 在此处 Sleep(3000);////////////////////////////////////////////////////////////////// ///////////////////////////sleep() cout<<endl; } }//2while() return 0; }/////////////////////////////////////////////////////主函数结束
void writer()//////////////////////////////////////////////////写者函数开始 { empty--;//P 操作改变信号量 wrIn--;//P 操作改变信号量 cout << " 写者"<<writc<<"获得资源" <<"("; SYSTEMTIME sys; GetLocalTime(&sys);//输出系统时间 cout<<" 系 统 时 间 : "<<sys.wHour<<":"<<sys.wMinute<<":"<<sys.wSecond<<":"<<sys.wMilliseconds<<")"< <endl; cout<<"请输入线程要写入的内容,以/结尾"<<endl; char ch='a'; ofstream outfile("f.txt",ios::out|ios::app); if(!outfile) { cerr<<"open file error!"<<endl; abort(); } while(ch!='/') { cin>>ch; outfile<<ch; } cout<<endl<<"*" <<"写者"<<writc<<"正在进行写操作.." << endl;