这是我参与「第四届青训营 」笔记创作活动的第3天
读写锁默认情况是写操作优先
int Rmutex=0,Wmutex=0;
int RW=0,readercount=0,writercount=0;
int startrw=0;
void Reader(){
// 防止同时涌入多个Reader
wait(Rmutex);
readercount++;
if(readercount==1){
// 关键点
wait(RW);
}
signal(Rmutex);
// ---------------------
wait(startrw);
//start reading...
siganl(startrw);
// ---------------------
wait(Rmutex);
readercount--;
if(readercount==0){
signal(RW);
}
signal(Rmutex);
}
void Writer(){
wait(Wmutex);
wait(RW);
//start writing
signal(startrw);
signal(Wmutex);
}
原方案
参考操作系统的读者写者问题
- 即读写操作互斥,可以同时存在多个读者,但只能有一个写者
- 优点:比较容易实现,代码量小,且可以保证读写操作的原子性
- 缺点:并发度低,相当于将整个文件目录树锁死,只能存在一个写进程
改进方案一
- 每个文件都视为一个独立的区域,可以对其进行读写操作,可以存在多个进程同时读该文件,但只能有一个进程写该文件
- 优点:并发度高;支持多个进程同一个文件目录树进行读写;且能保证读写的原子性,不会发生错误;时间开销小 ,适合文件数量少,但读写需求量大的情况。
- 缺点:空间的开销大,每个文件都会申请一副读写锁,文件数量过多则会大大消耗内存空间。
改进方案二
- 在方案一的基础上,每个文件需要读写的时候,则申请一副读写锁。
- 优点:并发度高;支持多个进程同一个文件目录树进行读写;且能保证读写的原子性,不会发生错误;空间开销小,适合读写需求低,且文件数量大的情况。
- 缺点:时间开销大,每次读写都要重新申请读写锁,浪费时间
改进方案三
- 综合方案二和方案三,构建一个读写锁池,由于文件读写时的并发程度是有限的,所以可以限定同一时刻并发的进程数,设其为n,每个进程需要读写数据时,则去读写锁池中申请读写锁;申请不到则排队;申请成功则该锁为某文件的读写锁,可以对文件进行读写操作,读写操作结束后则将读写锁归还
- 优点:并发高,同时对时间和空间的开销都不大,适用于读写情况和文件数量复杂的场景
- 缺点:不适用于特殊情况。