生产者_消费者问题[操作系统]

敬请T期待 Lv3

实验一

描述:

利用C++/C实现多线程的生产者-消费者问题。

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
#include<iostream>
#include<mutex>
#include<thread>
using namespace std;

int goods = 10;
int maxx = 100;
mutex suo;
mutex printr;
bool flag = false;
void producter(char name){
int need = 0;
while(1){
if(flag) return;
need = (rand() +1) % 10;
suo.lock();
if(goods + need <= maxx){
goods += need;
}
else{
need = maxx - goods;
goods = maxx;
}
suo.unlock();

printr.lock();
printf("%c生产者生产了%d商品,货架上有%d件商品\n",name,need,goods);
if(goods == maxx) printf("货架已满\n");
printr.unlock();

std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
void consumer(char name){
int need = 0;
while(1){
if(flag) return;
need = (rand() +1) % 10;
suo.lock();
if(goods - need > 0){
goods -= need;
}
else{
need = goods;
goods = 0;
}
suo.unlock();

printr.lock();
printf("%c消费者消费了%d商品,货架上有%d件商品\n", name,need,goods);
if(goods == 0) printf("货架已空\n");
printr.unlock();

std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
int main(){
srand(time(NULL));
thread pa(&producter,'A');
thread pb(&producter,'B');
thread pc(&producter,'C');
thread pd(&producter,'D');

thread ca(&consumer,'A');
thread cb(&consumer,'B');
thread cc(&consumer,'C');
thread cd(&consumer,'D');

char cinp;
while(cin>>cinp ){
if(cinp=='A') break;
}
flag = true;
pa.join();
pb.join();
pc.join();
pd.join();

ca.join();
cb.join();
cc.join();
cd.join();
return 0;
}

记录型信号量机制

利用记录型信号量机制解决生产者——消费者问题

在windows系统上实现

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
//记录型信号量
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

#define BUFFER_SIZE 10 // 缓冲区大小
#define MAX_ITEMS 20 // 生产者生产的最大项目数

// 全局变量
int buffer[BUFFER_SIZE]; // 缓冲区数组
int in = 0; // 下一个生产者将放入数据的位置
int out = 0; // 下一个消费者将取出数据的位置
int count = 0; // 缓冲区中当前项目的数量
HANDLE semEmpty; // empty;HEADLE 相当于 void*
HANDLE semFull; // full;
HANDLE mutex;
volatile BOOL stop = FALSE; // 用于停止消费者线程的标志

// 生产者线程函数
DWORD WINAPI Producer(LPVOID lpParam) {
for (int i = 0; i < MAX_ITEMS; i++) {
// 是否有空的缓冲区
WaitForSingleObject(semEmpty, INFINITE);

// 缓冲池是否空闲
WaitForSingleObject(mutex, INFINITE);

// 将数据放入缓冲区
buffer[in] = i;
in = (in + 1) % BUFFER_SIZE;
count++;

// 释放互斥锁
ReleaseMutex(mutex);

// 通知消费者缓冲区中有新项目
ReleaseSemaphore(semFull, 1, NULL);

// 模拟生产一个项目所需的时间
Sleep(100);
}
stop = TRUE;
return 0;
}

// 消费者线程函数
DWORD WINAPI Consumer(LPVOID lpParam) {
while (TRUE) {
// 等待缓冲区有项目
WaitForSingleObject(semFull, INFINITE);

// 缓冲池是否有空闲
WaitForSingleObject(mutex, INFINITE);

// 检查是否应该停止(在生产者线程完成后)
if (stop && count == 0) {
// 如果生产者已经停止并且缓冲区为空,则退出循环
ReleaseMutex(mutex);
break;
}

// 从缓冲区取出项目
int item = buffer[out];
out = (out + 1) % BUFFER_SIZE;
count--;

// 释放互斥锁
ReleaseMutex(mutex);

// 处理项目(这里只是简单地打印)
printf("Consumed: %d\n", item);

// 通知生产者缓冲区有空位
ReleaseSemaphore(semEmpty, 1, NULL);

// 模拟消费一个项目所需的时间
Sleep(150);
}

return 0;
}

int main() {
// 初始化信号量和互斥锁
semEmpty = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, NULL);
semFull = CreateSemaphore(NULL, 0, BUFFER_SIZE, NULL);
mutex = CreateMutex(NULL, FALSE, NULL);

// 创建生产者和消费者线程
HANDLE hProducer = CreateThread(NULL, 0, Producer, NULL, 0, NULL);
HANDLE hConsumer = CreateThread(NULL, 0, Consumer, NULL, 0, NULL);

// 等待生产者线程结束
WaitForSingleObject(hProducer, INFINITE);

// 等待消费者线程结束(确保所有项目都被消费)
// 注意:由于我们使用了stop标志和count变量来确保消费者线程在适当的时候停止,
// 所以这里我们只需要等待消费者线程自然结束即可。
WaitForSingleObject(hConsumer, INFINITE);

// 清理资源
CloseHandle(semEmpty);
CloseHandle(semFull);
CloseHandle(mutex);
CloseHandle(hProducer);
CloseHandle(hConsumer);

return 0;
}

AND型信号量机制

描述:

​ 利用AND型信号量机制解决一个进程需要获得两个或多个的共享资源后才能执行其任务的生产者——消费者问题

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
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>


#define BUFFER_SIZE 10

int buffer[BUFFER_SIZE]; // 共享缓冲区
int in = 0; // 生产者使用的索引
int out = 0; // 消费者使用的索引

// 信号量
sem_t empty, full;
sem_t mutex;

// 初始化信号量
void init_semaphores() {
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
}

// 生产者函数
void* producer(void* arg) {
int val = 0;
while (1) {
sem_wait(&empty); // 减少可用空间
sem_wait(&mutex); // 获取互斥锁

// 生产数据并放入缓冲区
buffer[in] = val;
printf("Produced %d\n", val);
in = (in + 1) % BUFFER_SIZE;
val++;

sem_post(&mutex); // 释放互斥锁
sem_post(&full); // 增加可用数据
}
return NULL;
}

// 消费者函数
void* consumer(void* arg) {
while (1) {
sem_wait(&full); // 减少可用数据
sem_wait(&mutex); // 获取互斥锁

// 从缓冲区消费数据
int val = buffer[out];
printf("Consumed %d\n", val);
out = (out + 1) % BUFFER_SIZE;

sem_post(&mutex); // 释放互斥锁
sem_post(&empty); // 增加可用空间
}
return NULL;
}

// 主函数
int main() {
pthread_t prod, cons;

init_semaphores();

// 创建生产者和消费者线程
if (pthread_create(&prod, NULL, producer, NULL) != 0) {
perror("Failed to create producer thread");
exit(EXIT_FAILURE);
}

if (pthread_create(&cons, NULL, consumer, NULL) != 0) {
perror("Failed to create consumer thread");
exit(EXIT_FAILURE);
}

// 等待线程结束(这里假定线程不会结束)
// 在实际应用中,您可能需要加入某种方式让线程能够退出
pthread_join(prod, NULL);
pthread_join(cons, NULL);

// 销毁信号量
sem_destroy(&empty);
sem_destroy(&full);
sem_destroy(&mutex);

return 0;
}

实验二:使用共享内存+信号量机制实现生产者-消费者问题

环境:Linux-kali

实验代码

productor.c

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
//使用共享内存+信号量机制实现生产者-消费者问题
// producor.c
# include <stdio.h>
# include <stdlib.h>
# include <sys/types.h>
# include <sys/ipc.h>
# include <semaphore.h>
# include <fcntl.h>
# include <sys/stat.h>
# include <sys/shm.h>

typedef struct {
int read;
int write;
char buf[10];
}shared_struct;

int main(int argc,char *argv[]){
int i = 0;
int shmid;
shared_struct *pbuf = 0;
int length = 0;
sem_t *full,*empty,*mutex;

//initialize full,empty,mutex semaphore
full = sem_open("full_sem",O_CREAT,0666,0);
empty = sem_open("empty_sem",O_CREAT, 0666,10);
mutex = sem_open("buf_mutex",O_CREAT,0666,1);

//shared memory
length = sizeof(shared_struct);
//create or get shared memory
shmid = shmget((key_t)1234,length,0666|IPC_CREAT);
//map to process space
pbuf = (shared_struct*)shmat(shmid,0,0);

for(i = 0;i<10;i++){
sleep(rand()%3);
sem_wait(empty);
sem_wait(mutex);
pbuf->buf[pbuf->write] = 'a'+ pbuf->write;
printf("Producer-%d: write %c\n",getpid(),pbuf->buf[pbuf->write]);
fflush(stdout);
pbuf->write = (++ pbuf->write) % 10;
sem_post(mutex);
sem_post(full);
}
shmdt((void*)pbuf);
sleep(10);
shmctl(shmid,IPC_RMID,0);
sem_close(full);
sem_close(empty);
sem_close(mutex);
sem_unlink("full_sem");
sem_unlink("empty_sem");
sem_unlink("buf_mutex");
exit(0);
}

customer.c

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
//costomer.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/shm.h>

typedef struct
{
/* data */
int read;
int write;
char buf[10];
}shared_struct;

int main(int argc,char *argv[]){
int i = 0;
int shmid;
shared_struct *pbuf = 0;
int length = 0;
sem_t *full,*empty,*mutex;

//initialize full,empty,mutex semaphore
full = sem_open("full_sem",O_CREAT,0666,0);
empty = sem_open("empty_sem",O_CREAT, 0666,10);
mutex = sem_open("buf_mutex",O_CREAT,0666,1);

//shared memory
length = sizeof(shared_struct);
//create or get shared memory
shmid = shmget((key_t)1234,length,0666|IPC_CREAT);
//map to process space
pbuf = (shared_struct*)shmat(shmid,0,0);

for(i=0;i<10;i++){
sleep(rand()%3);
sem_wait(full);
sem_wait(mutex);
printf("Customer-%d:read %c\n",getpid(),pbuf->buf[pbuf->read]);

fflush(stdout);
pbuf->buf[pbuf->read] = 'X';
pbuf->read = (++pbuf->read) % 10;
sem_post(mutex);
sem_post(empty);
}
shmdt((void*)pbuf);
sleep(10);
shmctl(shmid,IPC_RMID,0);
sem_close(full);
sem_close(empty);
sem_close(mutex);
sem_unlink("full_sem");
sem_unlink("empty_sem");
sem_unlink("buf_mutex");
exit(0);
}

编译:

1
2
gcc –o producer producer.c –lrt
gcc –o customer customer.c –lrt

运行:

1
./producer & ./producer & ./customer & ./customer  

实验结果:

consumer_prot

实验三:使用信号量进行互斥与同步

实验目的:

Ø进一步加深理解进程同步、互斥的概念

Ø进一步理解临界区、临界资源的概念

no_sem

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//no_sem.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main(int argc, char *argv[]){
char message = 'X';
int i = 0;
if(argc>1){
message = argv[1][0];
}
for(i = 0;i < 10; i++){
printf("%c",message);
fflush(stdout);
sleep(rand()%3);
printf("%c",message);
fflush(stdout);
sleep(rand()%2);
}
sleep(10);
exit(0);
}

代码过程及结果

1
2
3
4
5
6
7
8
9
10
11
12
13
//编译
┌──(root㉿kali)-[~/Desktop/OS/mutex]
└─# gcc -o no_sem no_sem.c -lrt
//运行
┌──(root㉿kali)-[~/Desktop/OS/mutex]
└─# ls
no_sem no_sem.c with_sem with_sem.c

┌──(root㉿kali)-[~/Desktop/OS/mutex]
└─# ./no_sem & ./no_sem o
[1] 437762
XoXXXoooXoXoXoXXXoooXoXoXoXoXoXXoXoXooXo[1] + done ./no_sem

with_sem

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
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<semaphore.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<unistd.h>

int main(int argc,char *argv[]){
char message = 'X';
int i =0;
if (argc > 1){
message = argv[1][0];
}
sem_t *mutex = sem_open("mysem",O_CREAT,0666,1);
for(i = 0;i<10;i++){
sem_wait(mutex);
printf("%c",message);
fflush(stdout);
sleep(rand()%3);
printf("%c",message);
fflush(stdout);
sem_post(mutex);
sleep(rand()%2);
}
sleep(10);
sem_close(mutex);
sem_unlink("mysem");
exit(0);
}

代码过程及结果

1
2
3
4
5
6
7
8
//编译
┌──(root㉿kali)-[~/Desktop/OS/mutex]
└─# gcc -o with_sem with_sem.c -lrt
//运行
┌──(root㉿kali)-[~/Desktop/OS/mutex]
└─# ./with_sem & ./with_sem o
[1] 1819
ooXXooXXooXXooXXooXXooXXooXXooXXooXXooXX [1] + done ./with_sem

chess

red_chess

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
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<semaphore.h>

int main(int argc, char *argv[]){
int i = 0;
sem_t *black = sem_open("chess_black_sem",O_CREAT,0666,1);
sem_t *red = sem_open("chess_red_sem",O_CREAT,0666,0);
for(i = 0;i<10;i++){
sem_wait(black);
if(i != 9){
printf("Red chess had moved,black chess go!\n");
}
else{
printf("Red chess Win!!!\n");
}
fflush(stdout);
sem_post(red);
}
sleep(10);
sem_close(black);
sem_close(red);
sem_unlink("chess_red_sem");
sem_unlink("chess_black_sem");
exit(0);
}

black_chess

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
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<semaphore.h>

int main(int argc, char *argv[]){
int i = 0;
sem_t *black = sem_open("chess_black_sem",O_CREAT,0666,1);
sem_t *red = sem_open("chess_red_sem",O_CREAT,0666,0);
for(i = 0;i<10;i++){
sem_wait(red);
if(i != 9){
printf("Black chess had moved, red chess go!\n");
}
else{
printf("Black chess lost!!!\n");
}
fflush(stdout);
sem_post(black);
}
sleep(10);
sem_close(black);
sem_close(red);
sem_unlink("chess_red_sem");
sem_unlink("chess_black_sem");
exit(0);
}

运行过程

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
┌──(root㉿kali)-[~/Desktop/OS/chess]
└─# ls
black_chess black_chess.c red_chess red_chess.c
//编译
┌──(root㉿kali)-[~/Desktop/OS/chess]
└─# gcc -o red_chess red_chess.c -lrt
┌──(root㉿kali)-[~/Desktop/OS/chess]
└─# gcc -o black_chess black_chess.c -lrt
//结果
┌──(root㉿kali)-[~/Desktop/OS/chess]
└─# ./red_chess & ./black_chess
[1] 5815
Red chess had moved,black chess go!
Black chess had moved, red chess go!
Red chess had moved,black chess go!
Black chess had moved, red chess go!
Red chess had moved,black chess go!
Black chess had moved, red chess go!
Red chess had moved,black chess go!
Black chess had moved, red chess go!
Red chess had moved,black chess go!
Black chess had moved, red chess go!
Red chess had moved,black chess go!
Black chess had moved, red chess go!
Red chess had moved,black chess go!
Black chess had moved, red chess go!
Red chess had moved,black chess go!
Black chess had moved, red chess go!
Red chess had moved,black chess go!
Black chess had moved, red chess go!
Red chess Win!!!
Black chess lost!!!
[1] + done ./red_chess

课程设计

设计内容

设计代码

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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*模拟实现生产者——消费者问题*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <stdlib.h>
#include <conio.h> // 用于键盘交互
#include <string.h> // 用于 memset 初始化缓冲区
#include <time.h> // 用于随机数种子生成

#define BUFFER_SIZE 20 // 缓冲区大小
#define PRODUCER_COUNT 3 // 生产者数量
#define CONSUMER_COUNT 3 // 消费者数量
#define MAX_SLEEP_TIME 3000 // 最大休眠时间(ms)

typedef struct {
int buffer[BUFFER_SIZE]; // 缓冲区数组
int in; // 入口指针
int out; // 出口指针
int count; // 当前缓冲区中的数据量
} Buffer;

Buffer shared_buffer = { {0}, 0, 0, 0 };
HANDLE empty_semaphore;
HANDLE full_semaphore;
CRITICAL_SECTION mutex; // 临界区
volatile LONG running = TRUE; // 运行标志,控制线程的运行状态
FILE* log_file;

// 设置独立随机数种子
void set_thread_random_seed(int thread_id) {
unsigned int seed = (unsigned int)(time(NULL) + thread_id);
srand(seed);
}

// 记录生产或消费操作
void log_operation(int id, int item, char type) {
EnterCriticalSection(&mutex);
const char* operation = (type == 'P') ? "生产者" : "消费者";
printf("%s %d %s了数据: %d\n", operation, id, (type == 'P') ? "生产" : "消费", item);
fprintf(log_file, "%s %d %s了数据: %d\n", operation, id, (type == 'P') ? "生产" : "消费", item);

printf("缓冲区状态: ");
fprintf(log_file, "缓冲区状态: ");
for (int i = 0; i < BUFFER_SIZE; i++) {
printf("%2d ", shared_buffer.buffer[i]);
fprintf(log_file, "%2d ", shared_buffer.buffer[i]);
}

printf("\n入口指针: %d, 出口指针: %d, 当前使用量: %d/%d\n",
shared_buffer.in, shared_buffer.out, shared_buffer.count, BUFFER_SIZE);
fprintf(log_file, "\n入口指针: %d, 出口指针: %d, 当前使用量: %d/%d\n",
shared_buffer.in, shared_buffer.out, shared_buffer.count, BUFFER_SIZE);
printf("----------------------------------------\n");
fprintf(log_file, "----------------------------------------\n");
LeaveCriticalSection(&mutex);
}

// 生产者线程函数
unsigned __stdcall producer(void* arg) {
int id = *(int*)arg;
set_thread_random_seed(id);

while (InterlockedCompareExchange(&running, TRUE, TRUE)) {
int item = rand() % 20 + 1;

WaitForSingleObject(empty_semaphore, INFINITE);
EnterCriticalSection(&mutex);

shared_buffer.buffer[shared_buffer.in] = item;
shared_buffer.in = (shared_buffer.in + 1) % BUFFER_SIZE;
shared_buffer.count++;

log_operation(id, item, 'P');

LeaveCriticalSection(&mutex);
ReleaseSemaphore(full_semaphore, 1, NULL);

Sleep(rand() % (MAX_SLEEP_TIME + 1));
}
return 0;
}

// 消费者线程函数
unsigned __stdcall consumer(void* arg) {
int id = *(int*)arg;
set_thread_random_seed(id);

while (InterlockedCompareExchange(&running, TRUE, TRUE)) {
WaitForSingleObject(full_semaphore, INFINITE);
EnterCriticalSection(&mutex);

int item = shared_buffer.buffer[shared_buffer.out];
shared_buffer.buffer[shared_buffer.out] = 0;
shared_buffer.out = (shared_buffer.out + 1) % BUFFER_SIZE;
shared_buffer.count--;

log_operation(id, item, 'C');

LeaveCriticalSection(&mutex);
ReleaseSemaphore(empty_semaphore, 1, NULL);

Sleep(rand() % (MAX_SLEEP_TIME + 1));
}
return 0;
}

// 创建线程
void create_threads(HANDLE* threads, int* ids, unsigned(__stdcall* func)(void*), int count) {
for (int i = 0; i < count; i++) {
ids[i] = i + 1;
threads[i] = (HANDLE)_beginthreadex(NULL, 0, func, &ids[i], 0, NULL);
}
}

// 主循环:监听 ESC 键退出
void wait_for_exit() {
while (InterlockedCompareExchange(&running, TRUE, TRUE)) {
if (_kbhit() && _getch() == 27) {
printf("检测到 ESC 键,准备退出程序...\n");
InterlockedExchange(&running, FALSE);
break;
}
Sleep(10);
}

// 通知所有线程退出
ReleaseSemaphore(full_semaphore, CONSUMER_COUNT, NULL);
ReleaseSemaphore(empty_semaphore, PRODUCER_COUNT, NULL);
}

int main() {
log_file = fopen("data.txt", "w");
if (log_file == NULL) {
printf("无法创建日志文件。\n");
return -1;
}

empty_semaphore = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, NULL);
full_semaphore = CreateSemaphore(NULL, 0, BUFFER_SIZE, NULL);
InitializeCriticalSection(&mutex);

memset(shared_buffer.buffer, 0, sizeof(shared_buffer.buffer));

HANDLE producers[PRODUCER_COUNT];
HANDLE consumers[CONSUMER_COUNT];
int producer_ids[PRODUCER_COUNT];
int consumer_ids[CONSUMER_COUNT];

printf("按 ESC 键退出程序...\n");
create_threads(producers, producer_ids, producer, PRODUCER_COUNT);
create_threads(consumers, consumer_ids, consumer, CONSUMER_COUNT);

wait_for_exit();

WaitForMultipleObjects(PRODUCER_COUNT, producers, TRUE, INFINITE);
WaitForMultipleObjects(CONSUMER_COUNT, consumers, TRUE, INFINITE);

DeleteCriticalSection(&mutex);
CloseHandle(empty_semaphore);
CloseHandle(full_semaphore);

for (int i = 0; i < PRODUCER_COUNT; i++) CloseHandle(producers[i]);
for (int i = 0; i < CONSUMER_COUNT; i++) CloseHandle(consumers[i]);

fclose(log_file);
printf("程序已退出。\n");
return 0;
}
  • Title: 生产者_消费者问题[操作系统]
  • Author: 敬请T期待
  • Created at : 2024-10-08 11:33:44
  • Updated at : 2025-01-03 00:17:36
  • Link: https://kingwempity.github.io/2024/10/08/生产者-消费者问题-操作系统/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments