1) 写者写时,不可读
2) 有别的读者正在读,可读
1) 有读者正在读,不可写
2) 有写者正在写,不可写
3) 无读者正在读,无写者正在写,可写
1) 有写者正在写或者等待写,须等到没有写者才能读
2) 没有写者,可以读
1) 写者与写者互斥。当其它写者正在写时,其它写者不能写。
2) 写者与读者互斥。之前只有读者在读,当写者出现时,必须等到之前的读者都读完才能写。这尊重了之前读者的意愿。
3) 写者可以有条件地插读者的队。当前有写者正写,有读者在等,这时来了新写者,新写者可以在那些读者之前执行。这不尊重
while(1)
{
pthread_mutex_lock(&writeLock);
{//临界区,限制只有一个写者修改数据
write();
}
pthread_mutex_unlock(&writeLock);
}
while(1)
{
pthread_mutex_lock(&accessWriterCnt);
{//临界区,希望修改 writerCnt,独占 writerCnt
writerCnt++;
if(writerCnt == 1){
//读者与写者互斥;使用readerLock来描述;
pthread_mutex_lock(&readerLock);
}
}
pthread_mutex_unlock(&accessWriterCnt);
pthread_mutex_lock(&writeLock);
{//临界区,限制只有一个写者修改数据
write();
}
pthread_mutex_unlock(&writeLock);
pthread_mutex_lock(&accessWriterCnt);
{//临界区,希望修改 writerCnt,独占 writerCnt
writerCnt--;
if(writerCnt == 0){
//阻止后续的读者加入待读队列
pthread_mutex_unlock(&readerLock);
}
}
pthread_mutex_unlock(&accessWriterCnt);
sleep(W_SLEEP);
}
while(1)
{
pthread_mutex_lock(&readerLock);
{//临界区
read();
}
pthread_mutex_unlock(&readerLock);
}
在上面的实现中,很明显的问题是,当一个读者执行 read() 的同时,不可能有另外的读者进入临界区并执行 read() 函数了。因此,必须确保在执行 read() 函数之前对readerLock解锁。代码类似于:
while(1)
{
pthread_mutex_lock(&readerLock);
pthread_mutex_unlock(&readerLock);
read();
}
于是乎,现在我们可以注意到,假如写者率先锁定了 readerLock , 那么后续的读者被阻塞在 pthread_mutex_lock(&readerLock); 了,这点很正确。在写者最终释放 readerLock 之前,可能有成千上万的读者都被阻塞在 readerLock 上, readerLock 释放之后,这些读者会竞争这 readerLock,嗯,这没什么问题。问题在于,此后,将可能有新的写者有写需求并希望获得这把锁(参照一下写者代码吧),那么,此时,写者不得不和成千上万的读者一起竞争 readerLock,由于将占有 readerLock 的人使随机的,写者在数量上不占优势,将进入饥饿状态。因此,这种实现无法满足“写者优先”的需求。
while(1)
{
pthread_mutex_lock(&outerLock);//成千上万的读者被锁在这里
pthread_mutex_lock(&readerLock);//只被一个读者占有
pthread_mutex_unlock(&readerLock);//释放时,写者将优先获得readerLock
pthread_mutex_unlock(&outerLock);
read();
}
pthread_mutex_lock(&writeLock);
{//临界区,限制只有一个写者修改数据
write();
}
pthread_mutex_unlock(&writeLock);
while(1)
{
pthread_mutex_lock(&outerLock);//成千上万的读者被锁在这里
pthread_mutex_lock(&readerLock);//只被一个读者占有
pthread_mutex_unlock(&readerLock);//释放时,写者将优先获得readerLock
pthread_mutex_unlock(&outerLock);
pthread_mutex_lock(&writeLock);//每个执行到这里的读者都企图对 writeLock 加锁
{//临界区
read();//同一时刻只能有一个读者在这里,无法实现读并发
}
pthread_mutex_unlock(&writeLock);
}
pthread_mutex_lock(&accessReaderCnt);
{//临界区
readerCnt++;
if(readerCnt == 1){//第一个并发读线程
pthread_mutex_lock(&writeLock);//在第一个并发读者这里开始禁止写者执行写操作
}
}
pthread_mutex_unlock(&accessReaderCnt);
pthread_mutex_lock(&accessReaderCnt);
{//临界区
readerCnt--;
if(readerCnt == 0){//最后一个并发读线程
pthread_mutex_unlock(&writeLock);//在最后一个并发读者read()结束后写者可以执行写操作
}
}
pthread_mutex_unlock(&accessReaderCnt);
while(1)
{
//代码段1 可能的位置 0
pthread_mutex_lock(&outerLock);//假如写者锁定了readerLock,那么成千上万的读者被锁在这里
//代码段1 可能的位置 1
pthread_mutex_lock(&readerLock);//只被一个读者占有
//代码段1 可能的位置 2
pthread_mutex_unlock(&readerLock);//释放时,写者将优先获得readerLock
//代码段1 可能的位置 3
pthread_mutex_unlock(&outerLock);
//代码段1 可能的位置 4
read();
pthread_mutex_lock(&accessReaderCnt);//代码段2
{//临界区
readerCnt--;
if(readerCnt == 0){
pthread_mutex_unlock(&writeLock);//在最后一个并发读者读完这里开始禁止写者执行写操作
}
}
pthread_mutex_unlock(&accessReaderCnt);
}
while(1)
{
pthread_mutex_lock(&outerLock);//假如写者锁定了readerLock,那么成千上万的读者被锁在这里
{//临界区
pthread_mutex_lock(&readerLock);//只被一个读者占有
{//临界区
pthread_mutex_lock(&accessReaderCnt);//代码段 1
{//临界区
readerCnt++;
if(readerCnt == 1){
pthread_mutex_lock(&writeLock);
}
}
pthread_mutex_unlock(&accessReaderCnt);
}
pthread_mutex_unlock(&readerLock);//释放时,写者将优先获得readerLock
}
pthread_mutex_unlock(&outerLock);
read();
pthread_mutex_lock(&accessReaderCnt);//代码段2
{//临界区
readerCnt--;
if(readerCnt == 0){
pthread_mutex_unlock(&writeLock);//在最后一个并发读者读完这里开始禁止写者执行写操作
}
}
pthread_mutex_unlock(&accessReaderCnt);
}
/*
* 多线程,读者优先
*/
#include "stdio.h"
#include
#include
#define N_WRITER 3 //写者数目
#define N_READER 5 //读者数目
#define W_SLEEP 1 //控制写频率
#define R_SLEEP 1 //控制读频率
pthread_t wid[N_WRITER],rid[N_READER];
const int MAX_RAND = 1000;//产生的最大随机数
pthread_mutex_t writeLock = PTHREAD_MUTEX_INITIALIZER;//同一时间只能一个人写文件,互斥
pthread_mutex_t accessReaderCnt = PTHREAD_MUTEX_INITIALIZER;//同一时间只能有一个人访问 readerCnt
int data = 0;
int readerCnt = 0;
void write()
{
int rd = rand();
printf("write %d\n",rd);
data = rd;
}
void read()
{
printf("read %d\n",data);
}
void * writer(void * in)
{
while(1)
{
pthread_mutex_lock(&writeLock);
write();
pthread_mutex_unlock(&writeLock);
sleep(W_SLEEP);
}
pthread_exit((void *) 0);
}
void * reader (void * in)
{
while(1)
{
pthread_mutex_lock(&accessReaderCnt);
readerCnt++;
if(readerCnt == 1){
pthread_mutex_lock(&writeLock);
}
pthread_mutex_unlock(&accessReaderCnt);
read();
pthread_mutex_lock(&accessReaderCnt);
readerCnt--;
if(readerCnt == 0){
pthread_mutex_unlock(&writeLock);
}
pthread_mutex_unlock(&accessReaderCnt);
sleep(R_SLEEP);
}
pthread_exit((void *) 0);
}
int main()
{
int i = 0;
for(i = 0; i < N_READER; i++)
{
pthread_create(&wid[i],NULL,reader,NULL);
}
for(i = 0; i < N_WRITER; i++)
{
pthread_create(&rid[i],NULL,writer,NULL);
}
while(1){
sleep(10);
}
return 0;
}
#include "stdio.h"
#include
#include
#define N_WRITER 2 //写者数目
#define N_READER 20 //读者数目
#define W_SLEEP 1 //控制写频率
#define R_SLEEP 0.5 //控制读频率
pthread_t wid[N_WRITER],rid[N_READER];
const int MAX_RAND = 1000;//产生的最大随机数
int data = 0;
int readerCnt = 0, writerCnt = 0;
pthread_mutex_t accessReaderCnt = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t accessWriterCnt = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t writeLock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t readerLock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t outerLock = PTHREAD_MUTEX_INITIALIZER;
void write()
{
int rd = rand()%MAX_RAND;
printf("write %d\n",rd);
data = rd;
}
void read()
{
printf("read %d\n",data);
}
void * writer(void * in)
{
while(1)
{
pthread_mutex_lock(&accessWriterCnt);
{//临界区,希望修改 writerCnt,独占 writerCnt
writerCnt++;
if(writerCnt == 1){
//阻止后续的读者加入待读队列
pthread_mutex_lock(&readerLock);
}
}
pthread_mutex_unlock(&accessWriterCnt);
pthread_mutex_lock(&writeLock);
{//临界区,限制只有一个写者修改数据
write();
}
pthread_mutex_unlock(&writeLock);
pthread_mutex_lock(&accessWriterCnt);
{//临界区,希望修改 writerCnt,独占 writerCnt
writerCnt--;
if(writerCnt == 0){
//阻止后续的读者加入待读队列
pthread_mutex_unlock(&readerLock);
}
}
pthread_mutex_unlock(&accessWriterCnt);
sleep(W_SLEEP);
}
pthread_exit((void *) 0);
}
void * reader (void * in)
{
while(1)
{
//假如写者锁定了readerLock,那么成千上万的读者被锁在这里
pthread_mutex_lock(&outerLock);
{//临界区
pthread_mutex_lock(&readerLock);//只被一个读者占有
{//临界区
pthread_mutex_lock(&accessReaderCnt);//代码段 1
{//临界区
readerCnt++;
if(readerCnt == 1){
pthread_mutex_lock(&writeLock);
}
}
pthread_mutex_unlock(&accessReaderCnt);
}
pthread_mutex_unlock(&readerLock);//释放时,写者将优先获得readerLock
}
pthread_mutex_unlock(&outerLock);
read();
pthread_mutex_lock(&accessReaderCnt);//代码段2
{//临界区
readerCnt--;
if(readerCnt == 0){
pthread_mutex_unlock(&writeLock);//在最后一个并发读者读完这里开始禁止写者执行写操作
}
}
pthread_mutex_unlock(&accessReaderCnt);
sleep(R_SLEEP);
}
pthread_exit((void *) 0);
}
int main()
{
int i = 0;
for(i = 0; i < N_READER; i++)
{
pthread_create(&rid[i],NULL,reader,NULL);
}
for(i = 0; i < N_WRITER; i++)
{
pthread_create(&wid[i],NULL,writer,NULL);
}
while(1){
sleep(10);
}
return 0;
}