├── README.md ├── build.sh ├── data ├── dataDist ├── fairCompetition.c ├── readFirst.c └── writeFirst.c /README.md: -------------------------------------------------------------------------------- 1 | # 读者写者问题 2 | [toc] 3 | ## 1.要求 4 | 在Linux环境下,创建一个进程,此进程包含n个线程。用这n个线程来表示n个读者或写者。每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。用信号量机制分别实现读者优先和写者优先的读者-写者问题。 5 | 读者-写者问题的读写操作限制(仅读者优先或写者优先): 6 | 1. 写-写互斥,即不能有两个写者同时进行写操作。 7 | 2. 读-写互斥,即不能同时有一个线程在读,而另一个线程在写。 8 | 3. 读-读允许,即可以有一个或多个读者在读。 9 | 10 | ## 2.概念 11 | 读者优先:当有读者在等待队列里等待时,写者进程不能开始 12 | 写者优先:当有写者在等待队列里等待时,读者进程不能开始 13 | 14 | ## 3.输入文件格式 15 | 测试数据文件包括n行测试数据,分别描述创建的n个线程是读者还是写者,以及读写操作的开始时间和持续时间。每行测试数据包括四个字段,各个字段间用空格分隔。第一字段为一个正整数,表示线程序号。第二字段表示相应线程角色,R表示读者,W表示写者。第三字段为一个正数,表示读写操作的开始时间:线程创建后,延迟相应时间(单位为秒)后发出对共享资源的读写申请。第四字段为一个正数,表示读写操作的持续时间。当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源 16 | 下面是一个测试数据文件的例子: 17 | ``` 18 | 1 R 3  5 19 | 2 W 4  5 20 | 3 R 5  2 21 | 4 R 6  5 22 | 5 W 7  3 23 | ``` 24 | 25 | ## 4.程序编译 26 | 公平竞争 27 | ```shell 28 | gcc fairCompetition.c -o fairCompetition.out -l pthread 29 | ``` 30 | 读者优先 31 | ```shell 32 | gcc readFirst.c -o readFirst.out -l pthread 33 | ``` 34 | 写者优先 35 | ```shell 36 | gcc writeFirst.c -o writeFirst.out -l pthread 37 | ``` 38 | 或直接运行build.sh 39 | ## 5.测试样例 40 | ### 正确性检验 41 | #### 公平竞争 42 | 输入 43 | ```shell 44 | ./fairCompetition.out < data 45 | ``` 46 | 输出 47 | ```shell 48 | [00秒]创建进程1 49 | [00秒]创建进程2 50 | [00秒]创建进程3 51 | [00秒]创建进程4 52 | [00秒]创建进程5 53 | [03秒]读者进程1等待读取 54 | [03秒]读者进程1开始读取 55 | [04秒]写者进程2等待写入 56 | [05秒]读者进程3等待读取 57 | [05秒]读者进程3开始读取 58 | [06秒]读者进程4等待读取 59 | [06秒]读者进程4开始读取 60 | [07秒]写者进程5等待写入 61 | [07秒]读者进程3读取结束 62 | [08秒]读者进程1读取结束 63 | [11秒]读者进程4读取结束 64 | [11秒]写者进程2开始写入 65 | [16秒]写者进程2写入结束 66 | [16秒]写者进程5开始写入 67 | [19秒]写者进程5写入结束 68 | ``` 69 | #### 读者优先 70 | 输入 71 | ```shell 72 | ./readFirst.out < data 73 | ``` 74 | 输出 75 | ``` 76 | [00秒]创建进程1 77 | [00秒]创建进程2 78 | [00秒]创建进程3 79 | [00秒]创建进程4 80 | [00秒]创建进程5 81 | [03秒]读者进程1等待读取 82 | [03秒]读者进程1开始读取 83 | [04秒]写者进程2等待写入 84 | [05秒]读者进程3等待读取 85 | [05秒]读者进程3开始读取 86 | [06秒]读者进程4等待读取 87 | [06秒]读者进程4开始读取 88 | [07秒]写者进程5等待写入 89 | [07秒]读者进程3读取结束 90 | [08秒]读者进程1读取结束 91 | [11秒]读者进程4读取结束 92 | [11秒]写者进程2开始写入 93 | [16秒]写者进程2写入结束 94 | [16秒]写者进程5开始写入 95 | [19秒]写者进程5写入结束 96 | ``` 97 | #### 写者优先 98 | 输入 99 | ```shell 100 | ./writeFirst.out < data 101 | ``` 102 | 输出 103 | ``` 104 | [00秒]创建进程1 105 | [00秒]创建进程2 106 | [00秒]创建进程3 107 | [00秒]创建进程4 108 | [00秒]创建进程5 109 | [03秒]读者进程1等待读取 110 | [03秒]读者进程1开始读取 111 | [04秒]写者进程2等待写入 112 | [05秒]读者进程3等待读取 113 | [06秒]读者进程4等待读取 114 | [07秒]写者进程5等待写入 115 | [08秒]读者进程1读取结束 116 | [08秒]写者进程2开始写入 117 | [13秒]写者进程2写入结束 118 | [13秒]写者进程5开始写入 119 | [16秒]读者进程3开始读取 120 | [16秒]读者进程4开始读取 121 | [16秒]写者进程5写入结束 122 | [18秒]读者进程3读取结束 123 | [21秒]读者进程4读取结束 124 | ``` 125 | ### 检验读者优先或写者优先正确性 126 | ```shell 127 | ./readFirst.out < dataDist 128 | ``` 129 | 样例输出 130 | (三种算法的不同之处在05秒和12秒) 131 | 132 | |公平竞争|读者优先|写者优先| 133 | |:-|:-|:-| 134 | |[00 秒]创建进程 1|[00 秒]创建进程 1|[00 秒]创建进程 1| 135 | |[00 秒]创建进程 2|[00 秒]创建进程 2|[00 秒]创建进程 2| 136 | |[00 秒]创建进程 3|[00 秒]创建进程 3|[00 秒]创建进程 3| 137 | |[00 秒]创建进程 4|[00 秒]创建进程 4|[00 秒]创建进程 4| 138 | |[00 秒]创建进程 5|[00 秒]创建进程 5|[00 秒]创建进程 5| 139 | |[00 秒]创建进程 6|[00 秒]创建进程 6|[00 秒]创建进程 6| 140 | |[01 秒]写者进程 1 等待写入|[01 秒]写者进程 1 等待写入|[01 秒]写者进程 1 等待写入 141 | |[01 秒]写者进程 1 开始写入|[01 秒]写者进程 1 开始写入|[01 秒]写者进程 1 开始写入 142 | |[02 秒]写者进程 2 等待写入|[02 秒]写者进程 2 等待写入|[02 秒]写者进程 2 等待写入 143 | |[03 秒]读者进程 3 等待读取|[03 秒]读者进程 3 等待读取|[03 秒]读者进程 3 等待读取 144 | |[05 秒]写者进程 1 写入结束|[05 秒]读者进程 3 开始读取|[05 秒]写者进程 1 写入结束 145 | |[05 秒]写者进程 2 开始写入|[05 秒]写者进程 1 写入结束|[05 秒]写者进程 2 开始写入 146 | |[06 秒]写者进程 2 写入结束|[06 秒]读者进程 3 读取结束|[06 秒]写者进程 2 写入结束 147 | |[06 秒]读者进程 3 开始读取|[06 秒]写者进程 2 开始写入|[06 秒]读者进程 3 开始读取 148 | |[07 秒]读者进程 3 读取结束|[07 秒]写者进程 2 写入结束|[07 秒]读者进程 3 读取结束 149 | |[08 秒]写者进程 4 等待写入|[08 秒]写者进程 4 等待写入|[08 秒]写者进程 4 等待写入 150 | |[08 秒]写者进程 4 开始写入|[08 秒]写者进程 4 开始写入|[08 秒]写者进程 4 开始写入 151 | |[09 秒]读者进程 5 等待读取|[09 秒]读者进程 5 等待读取|[09 秒]读者进程 5 等待读取 152 | |[10 秒]写者进程 6 等待写入|[10 秒]写者进程 6 等待写入|[10 秒]写者进程 6 等待写入 153 | |[12 秒]写者进程 4 写入结束|[12 秒]读者进程 5 开始读取|[12 秒]写者进程 4 写入结束 154 | |[12 秒]读者进程 5 开始读取|[12 秒]写者进程 4 写入结束|[12 秒]写者进程 6 开始写入 155 | |[13 秒]读者进程 5 读取结束|[13 秒]读者进程 5 读取结束|[13 秒]写者进程 6 写入结束 156 | |[13 秒]写者进程 6 开始写入|[13 秒]写者进程 6 开始写入|[13 秒]读者进程 5 开始读取 157 | |[14 秒]写者进程 6 写入结束|[14 秒]写者进程 6 写入结束|[14 秒]读者进程 5 读取结束 158 | ## 6.伪代码 159 | ### 公平竞争 160 | 在没有特别的优先级情况下,读者写者公平竞争。进程之间通过wrt的锁保证临界区访问的互斥性,先获得wrt锁的进程先执行。 161 | #### 读者 162 | ```c 163 | wait(mutex); 164 | ++reader_count; 165 | if(reader_count == 1) { 166 | wait(&wrt); 167 | } 168 | signal(mutex); 169 | 170 | // read 171 | 172 | wait(mutex); 173 | --reader_count; 174 | if(reader_count == 0) { 175 | signal(&wrt); 176 | } 177 | signal(mutex); 178 | ``` 179 | #### 写者 180 | ```c 181 | wait(&wrt); 182 | 183 | // write 184 | 185 | signal(&wrt); 186 | ``` 187 | ### 读者优先 188 | 读者优先和写者优先需要引入一个状态变量state,表明当前系统的状态。需要用到的几个状态量如下: 189 | - mutex:保证reader_count, writer_count, state变量访问的互斥性 190 | - Sig_read:允许读的信号量 191 | - Sig_wrt:允许写的信号量 192 | #### 读者 193 | ```c 194 | wait(mutex); 195 | ++reader_count; 196 | if(state == s_waiting || state == s_reading) { 197 | signal(Sig_read); 198 | state = s_reading; 199 | } 200 | signal(mutex); 201 | 202 | // read 203 | 204 | wait(mutex); 205 | --reader_count; 206 | if(reader_count == 0) { 207 | if(writer_count != 0) { 208 | signal(Sig_wrt); 209 | state = s_writing; 210 | } else { 211 | state = s_waiting; 212 | } 213 | } 214 | signal(mutex); 215 | ``` 216 | #### 写者 217 | ```c 218 | wait(mutex); 219 | ++writer_count; 220 | if(state == s_waiting) { 221 | signal(Sig_wrt); 222 | state = s_writing; 223 | } 224 | signal(mutex); 225 | 226 | // write 227 | 228 | wait(mutex); 229 | --writer_count; 230 | if(reader_count != 0) { 231 | signal(Sig_read); 232 | state = s_reading; 233 | } else if(writer_count != 0) { 234 | signal(Sig_wrt); 235 | state = s_writing; 236 | } else { 237 | state = s_waiting; 238 | } 239 | signal(mutex); 240 | ``` 241 | ### 写者优先 242 | #### 读者 243 | ```c 244 | wait(mutex); 245 | ++reader_count; 246 | if(state == s_waiting 247 | || (state == s_reading && writer_count == 0)) { 248 | signal(Sig_read); 249 | state = s_reading; 250 | } 251 | signal(mutex); 252 | 253 | // read 254 | 255 | wait(mutex); 256 | --reader_count; 257 | if(writer_count != 0) { 258 | // 有读者在等待 259 | sem_post(Sig_wrt); 260 | state = s_writing; 261 | } else if(reader_count == 0) { 262 | // 等待队列为空 263 | state = s_waiting; 264 | } 265 | signal(mutex); 266 | ``` 267 | #### 写者 268 | ```c 269 | wait(mutex); 270 | ++writer_count; 271 | if(state == s_waiting) { 272 | signal(Sig_wrt); 273 | state = s_writing; 274 | } 275 | signal(mutex); 276 | 277 | // write 278 | 279 | wait(mutex); 280 | --writer_count; 281 | if(writer_count != 0) { 282 | signal(Sig_wrt); 283 | state = s_writing; 284 | } else if(reader_count != 0) { 285 | for(int i=0; i!=reader_count; ++i) { 286 | signal(Sig_read); 287 | } 288 | state = s_reading; 289 | } else { 290 | state = s_waiting; 291 | } 292 | signal(mutex); 293 | ``` 294 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | # !/usr/bin/shell 2 | gcc fairCompetition.c -o fairCompetition.out -l pthread 3 | gcc readFirst.c -o readFirst.out -l pthread 4 | gcc writeFirst.c -o writeFirst.out -l pthread -------------------------------------------------------------------------------- /data: -------------------------------------------------------------------------------- 1 | 1 R 3 5 2 | 2 W 4 5 3 | 3 R 5 2 4 | 4 R 6 5 5 | 5 W 7 3 6 | -------------------------------------------------------------------------------- /dataDist: -------------------------------------------------------------------------------- 1 | 1 W 1 4 2 | 2 W 2 1 3 | 3 R 3 1 4 | 4 W 8 4 5 | 5 R 9 1 6 | 6 W 10 1 7 | -------------------------------------------------------------------------------- /fairCompetition.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef struct { 7 | int tid; 8 | int delay; 9 | int last; 10 | } Role; 11 | 12 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 13 | static pthread_mutex_t wrt = PTHREAD_MUTEX_INITIALIZER; 14 | int reader_count = 0; 15 | 16 | time_t startTime; 17 | 18 | void* reader(void* argPtr) { 19 | Role role = *(Role*)argPtr; 20 | sleep(role.delay); 21 | printf("[%02.0lf秒]读者进程%d等待读取\n", 22 | difftime(time(NULL), startTime), role.tid 23 | ); 24 | pthread_mutex_lock(&mutex); 25 | ++reader_count; 26 | if(reader_count == 1) { 27 | pthread_mutex_lock(&wrt); 28 | } 29 | pthread_mutex_unlock(&mutex); 30 | printf("[%02.0lf秒]读者进程%d开始读取\n", 31 | difftime(time(NULL), startTime), role.tid 32 | ); 33 | 34 | // read 35 | sleep(role.last); 36 | 37 | pthread_mutex_lock(&mutex); 38 | --reader_count; 39 | if(reader_count == 0) { 40 | pthread_mutex_unlock(&wrt); 41 | } 42 | pthread_mutex_unlock(&mutex); 43 | printf("[%02.0lf秒]读者进程%d读取结束\n", 44 | difftime(time(NULL), startTime), role.tid 45 | ); 46 | return NULL; 47 | } 48 | 49 | void* writer(void* argPtr) { 50 | Role role = *(Role*)argPtr; 51 | sleep(role.delay); 52 | printf("[%02.0lf秒]写者进程%d等待写入\n", 53 | difftime(time(NULL), startTime), role.tid 54 | ); 55 | pthread_mutex_lock(&wrt); 56 | printf("[%02.0lf秒]写者进程%d开始写入\n", 57 | difftime(time(NULL), startTime), role.tid 58 | ); 59 | // write 60 | sleep(role.last); 61 | pthread_mutex_unlock(&wrt); 62 | printf("[%02.0lf秒]写者进程%d写入结束\n", 63 | difftime(time(NULL), startTime), role.tid 64 | ); 65 | return NULL; 66 | } 67 | 68 | int main() { 69 | const int MAX_THREAD = 100; 70 | pthread_t tid[MAX_THREAD]; 71 | Role role[MAX_THREAD]; 72 | int tidEnd = 0; 73 | 74 | startTime = time(NULL); 75 | 76 | int arg_tid; 77 | int arg_delay; 78 | int arg_last; 79 | char arg_type; 80 | while(scanf("%d %c%d%d", &arg_tid, &arg_type, &arg_delay, &arg_last) == 4) { 81 | assert(tidEnd < MAX_THREAD); 82 | if(arg_type == 'R') { 83 | role[tidEnd].tid = arg_tid; 84 | role[tidEnd].delay = arg_delay; 85 | role[tidEnd].last = arg_last; 86 | pthread_create(tid + tidEnd, NULL, reader, role + tidEnd); 87 | } else { 88 | role[tidEnd].tid = arg_tid; 89 | role[tidEnd].delay = arg_delay; 90 | role[tidEnd].last = arg_last; 91 | pthread_create(tid + tidEnd, NULL, writer, role + tidEnd); 92 | } 93 | printf("[%02.0lf秒]创建进程%d\n", difftime(time(NULL), startTime), arg_tid); 94 | ++tidEnd; 95 | } 96 | 97 | for(int i=0; i!=tidEnd; ++i) { 98 | pthread_join(tid[i], NULL); 99 | } 100 | 101 | pthread_mutex_destroy(&mutex); 102 | pthread_mutex_destroy(&wrt); 103 | } -------------------------------------------------------------------------------- /readFirst.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | typedef struct { 8 | int tid; 9 | int delay; 10 | int last; 11 | } Role; 12 | 13 | enum { 14 | s_waiting, 15 | s_reading, 16 | s_writing 17 | } state = s_waiting; 18 | 19 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 20 | sem_t Sig_read; 21 | sem_t Sig_wrt; 22 | int reader_count = 0; 23 | int writer_count = 0; 24 | 25 | time_t startTime; 26 | 27 | // 读者进程 28 | void* reader(void* argPtr) { 29 | Role role = *(Role*)argPtr; 30 | sleep(role.delay); 31 | printf("[%02.0lf秒]读者进程%d等待读取\n", 32 | difftime(time(NULL), startTime), role.tid 33 | ); 34 | 35 | pthread_mutex_lock(&mutex); 36 | ++reader_count; 37 | if(state == s_waiting || state == s_reading) { 38 | sem_post(&Sig_read); 39 | state = s_reading; 40 | } 41 | pthread_mutex_unlock(&mutex); 42 | sem_wait(&Sig_read); 43 | 44 | printf("[%02.0lf秒]读者进程%d开始读取\n", 45 | difftime(time(NULL), startTime), role.tid 46 | ); 47 | 48 | // read 49 | sleep(role.last); 50 | 51 | pthread_mutex_lock(&mutex); 52 | --reader_count; 53 | if(reader_count == 0) { 54 | if(writer_count != 0) { 55 | sem_post(&Sig_wrt); 56 | state = s_writing; 57 | } else { 58 | state = s_waiting; 59 | } 60 | } 61 | pthread_mutex_unlock(&mutex); 62 | 63 | printf("[%02.0lf秒]读者进程%d读取结束\n", 64 | difftime(time(NULL), startTime), role.tid 65 | ); 66 | return NULL; 67 | } 68 | 69 | // 写者进程 70 | void* writer(void* argPtr) { 71 | Role role = *(Role*)argPtr; 72 | sleep(role.delay); 73 | printf("[%02.0lf秒]写者进程%d等待写入\n", 74 | difftime(time(NULL), startTime), role.tid 75 | ); 76 | pthread_mutex_lock(&mutex); 77 | ++writer_count; 78 | if(state == s_waiting) { 79 | sem_post(&Sig_wrt); 80 | state = s_writing; 81 | } 82 | pthread_mutex_unlock(&mutex); 83 | 84 | sem_wait(&Sig_wrt); 85 | printf("[%02.0lf秒]写者进程%d开始写入\n", 86 | difftime(time(NULL), startTime), role.tid 87 | ); 88 | // write 89 | sleep(role.last); 90 | 91 | pthread_mutex_lock(&mutex); 92 | --writer_count; 93 | if(reader_count != 0) { 94 | sem_post(&Sig_read); 95 | state = s_reading; 96 | } else if(writer_count != 0) { 97 | sem_post(&Sig_wrt); 98 | state = s_writing; 99 | } else { 100 | state = s_waiting; 101 | } 102 | pthread_mutex_unlock(&mutex); 103 | 104 | printf("[%02.0lf秒]写者进程%d写入结束\n", 105 | difftime(time(NULL), startTime), role.tid 106 | ); 107 | return NULL; 108 | } 109 | 110 | int main() { 111 | const int MAX_THREAD = 100; 112 | // 读写进程队列 113 | pthread_t tid[MAX_THREAD]; 114 | Role role[MAX_THREAD]; 115 | int tidEnd = 0; 116 | 117 | // 初始化信号量 118 | sem_init(&Sig_read, 0, 0); 119 | sem_init(&Sig_wrt, 0, 0); 120 | 121 | startTime = time(NULL); 122 | 123 | int arg_tid; 124 | int arg_delay; 125 | int arg_last; 126 | char arg_type; 127 | while(scanf("%d %c%d%d", &arg_tid, &arg_type, &arg_delay, &arg_last) == 4) { 128 | assert(tidEnd < MAX_THREAD); 129 | if(arg_type == 'R') { 130 | role[tidEnd].tid = arg_tid; 131 | role[tidEnd].delay = arg_delay; 132 | role[tidEnd].last = arg_last; 133 | pthread_create(tid + tidEnd, NULL, reader, role + tidEnd); 134 | } else { 135 | role[tidEnd].tid = arg_tid; 136 | role[tidEnd].delay = arg_delay; 137 | role[tidEnd].last = arg_last; 138 | pthread_create(tid + tidEnd, NULL, writer, role + tidEnd); 139 | } 140 | printf("[%02.0lf秒]创建进程%d\n", difftime(time(NULL), startTime), arg_tid); 141 | ++tidEnd; 142 | } 143 | 144 | for(int i=0; i!=tidEnd; ++i) { 145 | pthread_join(tid[i], NULL); 146 | } 147 | 148 | // 销毁信号量 149 | pthread_mutex_destroy(&mutex); 150 | sem_destroy(&Sig_read); 151 | sem_destroy(&Sig_wrt); 152 | } -------------------------------------------------------------------------------- /writeFirst.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | typedef struct { 8 | int tid; 9 | int delay; 10 | int last; 11 | } Role; 12 | 13 | enum { 14 | s_waiting, 15 | s_reading, 16 | s_writing 17 | } state = s_waiting; 18 | 19 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 20 | sem_t Sig_read; 21 | sem_t Sig_wrt; 22 | int reader_count = 0; 23 | int writer_count = 0; 24 | 25 | time_t startTime; 26 | 27 | // 读者进程 28 | void* reader(void* argPtr) { 29 | Role role = *(Role*)argPtr; 30 | sleep(role.delay); 31 | printf("[%02.0lf秒]读者进程%d等待读取\n", 32 | difftime(time(NULL), startTime), role.tid 33 | ); 34 | 35 | pthread_mutex_lock(&mutex); 36 | ++reader_count; 37 | if(state == s_waiting 38 | || (state == s_reading && writer_count == 0)) { 39 | sem_post(&Sig_read); 40 | state = s_reading; 41 | } 42 | pthread_mutex_unlock(&mutex); 43 | sem_wait(&Sig_read); 44 | 45 | printf("[%02.0lf秒]读者进程%d开始读取\n", 46 | difftime(time(NULL), startTime), role.tid 47 | ); 48 | 49 | // read 50 | sleep(role.last); 51 | 52 | pthread_mutex_lock(&mutex); 53 | --reader_count; 54 | if(writer_count != 0) { 55 | // 有读者在等待 56 | sem_post(&Sig_wrt); 57 | state = s_writing; 58 | } else if(reader_count == 0) { 59 | // 等待队列为空 60 | state = s_waiting; 61 | } 62 | pthread_mutex_unlock(&mutex); 63 | 64 | printf("[%02.0lf秒]读者进程%d读取结束\n", 65 | difftime(time(NULL), startTime), role.tid 66 | ); 67 | return NULL; 68 | } 69 | 70 | // 写者进程 71 | void* writer(void* argPtr) { 72 | Role role = *(Role*)argPtr; 73 | sleep(role.delay); 74 | printf("[%02.0lf秒]写者进程%d等待写入\n", 75 | difftime(time(NULL), startTime), role.tid 76 | ); 77 | pthread_mutex_lock(&mutex); 78 | ++writer_count; 79 | if(state == s_waiting) { 80 | sem_post(&Sig_wrt); 81 | state = s_writing; 82 | } 83 | pthread_mutex_unlock(&mutex); 84 | 85 | sem_wait(&Sig_wrt); 86 | printf("[%02.0lf秒]写者进程%d开始写入\n", 87 | difftime(time(NULL), startTime), role.tid 88 | ); 89 | // write 90 | sleep(role.last); 91 | 92 | pthread_mutex_lock(&mutex); 93 | --writer_count; 94 | if(writer_count != 0) { 95 | sem_post(&Sig_wrt); 96 | state = s_writing; 97 | } else if(reader_count != 0) { 98 | for(int i=0; i!=reader_count; ++i) { 99 | sem_post(&Sig_read); 100 | } 101 | state = s_reading; 102 | } else { 103 | state = s_waiting; 104 | } 105 | pthread_mutex_unlock(&mutex); 106 | 107 | printf("[%02.0lf秒]写者进程%d写入结束\n", 108 | difftime(time(NULL), startTime), role.tid 109 | ); 110 | return NULL; 111 | } 112 | 113 | int main() { 114 | const int MAX_THREAD = 100; 115 | // 读写进程队列 116 | pthread_t tid[MAX_THREAD]; 117 | Role role[MAX_THREAD]; 118 | int tidEnd = 0; 119 | 120 | // 初始化信号量 121 | sem_init(&Sig_read, 0, 0); 122 | sem_init(&Sig_wrt, 0, 0); 123 | 124 | startTime = time(NULL); 125 | 126 | int arg_tid; 127 | int arg_delay; 128 | int arg_last; 129 | char arg_type; 130 | while(scanf("%d %c%d%d", &arg_tid, &arg_type, &arg_delay, &arg_last) == 4) { 131 | assert(tidEnd < MAX_THREAD); 132 | if(arg_type == 'R') { 133 | role[tidEnd].tid = arg_tid; 134 | role[tidEnd].delay = arg_delay; 135 | role[tidEnd].last = arg_last; 136 | pthread_create(tid + tidEnd, NULL, reader, role + tidEnd); 137 | } else { 138 | role[tidEnd].tid = arg_tid; 139 | role[tidEnd].delay = arg_delay; 140 | role[tidEnd].last = arg_last; 141 | pthread_create(tid + tidEnd, NULL, writer, role + tidEnd); 142 | } 143 | printf("[%02.0lf秒]创建进程%d\n", difftime(time(NULL), startTime), arg_tid); 144 | ++tidEnd; 145 | } 146 | 147 | for(int i=0; i!=tidEnd; ++i) { 148 | pthread_join(tid[i], NULL); 149 | } 150 | 151 | // 销毁信号量 152 | pthread_mutex_destroy(&mutex); 153 | sem_destroy(&Sig_read); 154 | sem_destroy(&Sig_wrt); 155 | } --------------------------------------------------------------------------------