1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
#include <semaphore.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include "deque.h"
#define BUFSIZE 1024
#define BUFCNT 10
sem_t* sem_r;
sem_t* sem_w;
pthread_mutex_t w_mutex;
pthread_mutex_t r_mutex;
int cnt = 0;
int shmid;
char (*shmaddr)[BUFSIZE];
deque* q;
void shm_read() {
pthread_mutex_lock(&r_mutex);
int ret = deque_popleft(q);
printf("tid: %ld, read: %s\n", pthread_self(), shmaddr[ret]);
pthread_mutex_unlock(&r_mutex);
}
void shm_write() {
pthread_mutex_lock(&w_mutex);
int ret = deque_push(q);
sprintf(shmaddr[ret], "%d", cnt);
printf("%ld write: %d\n", pthread_self(), cnt);
cnt++;
pthread_mutex_unlock(&w_mutex);
}
void* writer(void* arg) {
while (1) {
// 等待写空间
sem_wait(sem_w);
shm_write();
// 读信号量+1
sem_post(sem_r);
usleep(200000);
}
}
void* reader(void* arg) {
while (1) {
// 等待读空间
sem_wait(sem_r);
shm_read();
// 写信号量+1
sem_post(sem_w);
sleep(1);
}
}
int main(int argc, char const *argv[]) {
q = deque_init(BUFCNT);
pthread_mutex_init(&w_mutex, NULL);
pthread_mutex_init(&r_mutex, NULL);
// 创建一个读信号量,不存在则创建,存在就清空内容
sem_r = sem_open("sem_r", O_CREAT, 0666, 0);
sem_init(sem_r, 0, 0);
if (sem_r == SEM_FAILED) {
perror("sem_r error");
}
// 创建一个写信号量, 循环队列实际容量减一
sem_w = sem_open("sem_w", O_CREAT, 0666, BUFCNT);
sem_init(sem_w, 0, BUFCNT);
if (sem_w == SEM_FAILED) {
perror("sem_w error");
}
//1 申请key值
key_t key = ftok(".", 100);
if(key == -1)
{
perror("ftok");
return -1;
}
//2 根据key获取共享内存ID号, 如果该共享内存不存在,则创建
shmid = shmget(key, BUFSIZE*BUFCNT, IPC_CREAT | 0666);
if(shmid == -1) {
perror("shmget");
return -1;
}
//3 将共享内存 映射到用户的虚拟内存空间中
shmaddr = shmat(shmid, NULL, 0);
if(shmaddr == (void*)-1) {
perror("shmat");
return -1;
}
// 创建一个线程用来写
pthread_t tidw_1;
pthread_create(&tidw_1, NULL, writer, NULL);
pthread_t tidw_2;
pthread_create(&tidw_2, NULL, writer, NULL);
// 创建一个线程用来读
pthread_t tidr_1;
pthread_create(&tidr_1, NULL, reader, NULL);
pthread_t tidr_2;
pthread_create(&tidr_2, NULL, reader, NULL);
pthread_t tidr_3;
pthread_create(&tidr_3, NULL, reader, NULL);
pthread_join(tidw_1, NULL);
pthread_join(tidw_2, NULL);
pthread_join(tidr_1, NULL);
pthread_join(tidr_2, NULL);
pthread_join(tidr_3, NULL);
// 4 解除映射
shmdt(shmaddr);
// 5 删除共享内存
shmctl(shmid, IPC_RMID, NULL);
// 6 删除信号量
sem_unlink("sem_r");
sem_unlink("sem_w");
deque_destroy(q);
return 0;
}
|