1.生产者/消费者模型为依据,在Windows环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥.先初始化缓冲区长度为6:typedef int buffer_item;#define BUFFER_SIZE 6 2.创建三个信号量:mutex信号量,作为互斥信号量,用于互斥的访问缓冲区; full信号量,判断缓冲区是否有值,初值为0; empty信号量,判断缓冲区是否有空缓冲区,初值为缓冲区数。 3.缓冲将会被用于两个函数:insert_item()和remove_item()。 4.编写两个函数:DWORD WINAPI producer(void *param)和DWORD WINAPI consumer(void *param),随机函数rand()产生随机数。 5.编写main()函数,主要功能是: int main(int argc, char *argv[]) { /1. Get command line arguments argv[1], argv[2], argv[3]/ /2. Initialize buffer/ /3. Create producer threads(s)/ /4. Create consumer threads(s)/ /5. Sleep/ /6.Exit/ } 6.打印出相应结果。
时间: 2023-06-17 09:05:44 浏览: 141
生产者与消费者 进程的同步与互斥模拟
5星 · 资源好评率100%
以下是一个可能的实现,注意代码中的注释:
```
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define BUFFER_SIZE 6
typedef int buffer_item;
// 三个信号量,mutex信号量用于互斥的访问缓冲区,full信号量用于判断缓冲区是否有值,empty信号量用于判断缓冲区是否有空缓冲区
HANDLE mutex, full, empty;
// 缓冲区和指向缓冲区的指针
buffer_item buffer[BUFFER_SIZE];
int in = 0, out = 0;
// 插入一个item到缓冲区中,如果成功返回0,否则返回-1
int insert_item(buffer_item item) {
WaitForSingleObject(empty, INFINITE); // 判断是否有空缓冲区可用
WaitForSingleObject(mutex, INFINITE); // 互斥地访问缓冲区
buffer[in] = item;
in = (in + 1) % BUFFER_SIZE;
ReleaseSemaphore(mutex, 1, NULL); // 解除互斥访问缓冲区
ReleaseSemaphore(full, 1, NULL); // 增加full信号量
return 0;
}
// 从缓冲区中取出一个item,如果成功返回0,否则返回-1
int remove_item(buffer_item *item) {
WaitForSingleObject(full, INFINITE); // 判断是否有值可用
WaitForSingleObject(mutex, INFINITE); // 互斥地访问缓冲区
*item = buffer[out];
out = (out + 1) % BUFFER_SIZE;
ReleaseSemaphore(mutex, 1, NULL); // 解除互斥访问缓冲区
ReleaseSemaphore(empty, 1, NULL); // 增加empty信号量
return 0;
}
// 生产者线程
DWORD WINAPI producer(LPVOID lpParam) {
buffer_item item;
while (1) {
Sleep(rand() % 5000); // 随机等待一段时间
item = rand() % 100;
if (insert_item(item) != 0) {
printf("Error: Failed to insert item\n");
} else {
printf("Producer produced %d\n", item);
}
}
return 0;
}
// 消费者线程
DWORD WINAPI consumer(LPVOID lpParam) {
buffer_item item;
while (1) {
Sleep(rand() % 5000); // 随机等待一段时间
if (remove_item(&item) != 0) {
printf("Error: Failed to remove item\n");
} else {
printf("Consumer consumed %d\n", item);
}
}
return 0;
}
int main(int argc, char *argv[]) {
int i, n_producer, n_consumer;
DWORD *producer_ids, *consumer_ids;
HANDLE *producers, *consumers;
if (argc != 4) {
printf("Usage: %s <sleep time> <# producer threads> <# consumer threads>\n", argv[0]);
return -1;
}
srand(time(NULL)); // 随机数种子初始化
// 初始化信号量
mutex = CreateSemaphore(NULL, 1, 1, NULL);
full = CreateSemaphore(NULL, 0, BUFFER_SIZE, NULL);
empty = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, NULL);
// 获取命令行参数
int sleep_time = atoi(argv[1]);
n_producer = atoi(argv[2]);
n_consumer = atoi(argv[3]);
// 创建线程
producer_ids = (DWORD*)malloc(n_producer * sizeof(DWORD));
consumer_ids = (DWORD*)malloc(n_consumer * sizeof(DWORD));
producers = (HANDLE*)malloc(n_producer * sizeof(HANDLE));
consumers = (HANDLE*)malloc(n_consumer * sizeof(HANDLE));
for (i = 0; i < n_producer; i++) {
producer_ids[i] = i;
producers[i] = CreateThread(NULL, 0, producer, &producer_ids[i], 0, NULL);
}
for (i = 0; i < n_consumer; i++) {
consumer_ids[i] = i;
consumers[i] = CreateThread(NULL, 0, consumer, &consumer_ids[i], 0, NULL);
}
// 等待线程结束
Sleep(sleep_time);
for (i = 0; i < n_producer; i++) {
TerminateThread(producers[i], 0);
}
for (i = 0; i < n_consumer; i++) {
TerminateThread(consumers[i], 0);
}
// 释放资源
CloseHandle(mutex);
CloseHandle(full);
CloseHandle(empty);
free(producer_ids);
free(consumer_ids);
free(producers);
free(consumers);
return 0;
}
```
该程序创建了n个生产者线程和n个消费者线程,它们通过缓冲区进行同步和互斥访问。每个生产者线程随机地等待一段时间后,生成一个随机数并插入到缓冲区中;每个消费者线程也随机地等待一段时间后,从缓冲区中取出一个值并打印出来。通过信号量的控制,保证了缓冲区的同步和互斥访问。
阅读全文