1、读者写者模型的概念:
读者和写者模型是操作系统中的一种同步与互斥机制,我们知道在一些程序中存在读者写者问题,就是对某些资源的访问会存在两种可能的情况:一种就是写操作,写操作是可以独占资源的,也就是具有排他性;另一种情况就是读操作,在读操作中可以有多个资源并发的去访问某种资源,它的访问方式是共享的。这种模型是从对文件的读写操作中总结出的一种模型,同上篇博客(321原则)。
(1)3种关系:1).读者和读者之间,读者与读者之间是可以并发的访问某种资源的,所以他们之间是共享关系。
2).读者和写者之间,我们知道对一个文件来说是不可以既读又写的,可能会导致数据的二义性问题。读者和 写着之间是互斥和同步的关系。
3).写着和写着之间,存在互斥的关系。
(2)2种角色:
读者和写着。
(3)1种场所。
读者写着要具备的条件:
-
写者是排它性的,即在有多个写者的情况下,只能有一个写者占有“仓库”;
-
读者的并行机制:可以运行多个读者去访问仓库;
-
如果读者占有了仓库,那么写者则不能占有;
2、读者写者模型与生产者与消费者模型的区别
读者写者模型与消费者和生产者模型类似,但也有不同的地方,最明显的一个特点是在读者写者模型中,多个读者之间可以共享“仓库”,读者与读者之间采用了并行机制;而在消费者和生产者模型中,消费者只能有一个独占仓库,消费者与消费者是竞争关系,也就是说,在生产者消费者模型中,生产者产生数据,消费者必须把数据拿走,才算是消费成功了。但是对于我们的读写模型来说,读者只需读到数据即可,它不需要拿走数据。
3、(1)读者先读的代码:
运行结果:
(2)写者先写的代码:
1 #include<stdio.h>
2 #include<pthread.h>
3
4 int book=0;
5 pthread_rwlock_t rwlock;
6
7 void *myread(void *arg)
8 {
9 while(1)
10 {
11 ┊ if(pthread_rwlock_rdlock(&rwlock)!=0)
12 ┊ {
13 ┊ ┊ printf(“writer is writing…\n”);
14 ┊ }
15 ┊ else
16 ┊ {
17 ┊ printf(“read book done:%d\n”,book);
18 ┊ ┊ sleep(4);
19 ┊ }
20 }
21 }
22
23 void *mywrite(void *arg)
24 {
25 sleep(1);
26 while(1)
27 {
28 ┊ if(pthread_rwlock_wrlock(&rwlock)!=0)
29 ┊ {
30 ┊ ┊ printf(“reader is reading…\n”);
31 ┊ }
32 ┊ else
33 ┊ {
34 ┊ book++;
35 ┊ printf(“write book done:%d\n”,book);
36 ┊ sleep(5);
37 ┊ pthread_rwlock_unlock(&rwlock);
38 ┊ }
39 }
40 }
41
42 int main()
43 {
44 pthread_rwlock_init(&rwlock,NULL);
45 pthread_t r,w;
46 pthread_create(&r,NULL,myread ,NULL);
47 pthread_create(&w,NULL,mywrite,NULL);
48
49 pthread_join(r,NULL);
50 pthread_join(w,NULL);
51 pthread_rwlock_destroy(&rwlock);
52 return 0;
53 }
运行结果:
4、读写锁:
读写锁是一种特殊的自旋锁
,
专门处理多读少写的情况,它把共享资源的访问者划分为读者和写者,读者只能对共享资源进行读访问,写者则需要对共享资源进行写操作。这种锁相对于自旋锁而言,能提高并发性,因为在多处理系统中,它允许同时有多个读者来访问共享资源,最大可能的读写数为实际的逻辑CPU数。写者是排他性的,
一个读写锁同时只能有一个写着或者是多个读者(与CPU数无关),但是不能同时即有读者又有写者。读写锁相对互斥锁来说,可以允许多个线程同时占用读模式的读写锁,具有更高的试用性和并行性;
读写锁与互斥量类似,不过读写锁允许更高的并行性。它有三种状态:读模式下加锁状态、写模式下加锁状态、不加锁状态,另外,一次只有一个线程可以占用写模式下的读写锁,但是可以有多个线程可以占有读模式下的读写锁。
读写锁状态:
1)
写加锁状态:当处于写加锁状态时,在被解锁之前,所有试图对锁进行访问的进行都会被阻塞;
2)读加锁状态:当处于读加锁状态时,所有试图以读模式对这个锁进行访问的线程都可以获得访问权,但是任何 以写模式对此锁进行访问的线程都会被阻塞,直到所有的线程都释放他们的读状态锁为止。
注意
:当读写锁处于读模式加锁的状态时,这时有一个线程试图以写模式来获取锁,读写锁通常会阻塞随后的读模式锁请求,这样做事为了避免读模式锁长期占用资源,导致写模式饥饿。
(5)
读者写者问题的读写操作限制(包括读者优先和写者优先)
:
读者优先指的是除非有写者在写文件,否则读者不需要等待。写者优先与读者优先相类似,不同之处在于一旦一个写者到来,它应该尽快对文件进行写操作,如果有一个写者再等待,则新到来的读者不允许进行读操作。
- 读者优先的附加限制:如果读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。
- 写者优先的附加限制:如果一个读者申请进行读操作时已有另一个写者正在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始操作。