生产者/消费者模型为依据,在Windows环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥 核心代码: 1.先初始化缓冲区长度为6: /*buffer.h*/ typedef int buffer_item; #define BUFFER_SIZE 6 1.创建三个信号量:mutex信号量,作为互斥信号量,用于互斥的访问缓冲区; full信号量,判断缓冲区是否有值,初值为0; empty信号量,判断缓冲区是否有空缓冲区,初值为缓冲区数。 2.缓冲将会被用于两个函数:insert_item()和remove_item()。 3.编写两个函数:DWORD WINAPI producer(void *param)和DWORD WINAPI consumer(void *param),随机函数rand()产生随机数。 4.编写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*/ } 5.打印出相应结果。
时间: 2023-06-19 19:03:32 浏览: 130
下面是一个简单的生产者/消费者模型的实现,基于Windows API中的信号量来实现同步与互斥:
/* buffer.h */
typedef int buffer_item;
#define BUFFER_SIZE 6
/* global variables */
buffer_item buffer[BUFFER_SIZE];
HANDLE mutex;
HANDLE full;
HANDLE empty;
int buffer_pos;
/* function prototypes */
int insert_item(buffer_item item);
int remove_item(buffer_item *item);
DWORD WINAPI producer(void *param);
DWORD WINAPI consumer(void *param);
int main(int argc, char *argv[]) {
/* check command line arguments */
if (argc != 4) {
fprintf(stderr, "Usage: %s <sleep time> <num of producers> <num of consumers>\n", argv[0]);
return -1;
}
/* initialize buffer */
buffer_pos = 0;
mutex = CreateSemaphore(NULL, 1, 1, NULL);
full = CreateSemaphore(NULL, 0, BUFFER_SIZE, NULL);
empty = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, NULL);
/* create producer threads */
int sleep_time = atoi(argv[1]);
int num_producers = atoi(argv[2]);
for (int i = 0; i < num_producers; i++) {
DWORD producer_id;
HANDLE producer_handle = CreateThread(NULL, 0, producer, &sleep_time, 0, &producer_id);
if (producer_handle == NULL) {
fprintf(stderr, "Error creating producer thread!\n");
return -1;
}
CloseHandle(producer_handle);
}
/* create consumer threads */
int num_consumers = atoi(argv[3]);
for (int i = 0; i < num_consumers; i++) {
DWORD consumer_id;
HANDLE consumer_handle = CreateThread(NULL, 0, consumer, &sleep_time, 0, &consumer_id);
if (consumer_handle == NULL) {
fprintf(stderr, "Error creating consumer thread!\n");
return -1;
}
CloseHandle(consumer_handle);
}
/* sleep for user-specified time */
Sleep(sleep_time * 1000);
/* exit */
return 0;
}
int insert_item(buffer_item item) {
WaitForSingleObject(empty, INFINITE);
WaitForSingleObject(mutex, INFINITE);
if (buffer_pos >= BUFFER_SIZE) {
ReleaseSemaphore(mutex, 1, NULL);
ReleaseSemaphore(empty, 1, NULL);
return -1;
}
buffer[buffer_pos++] = item;
ReleaseSemaphore(mutex, 1, NULL);
ReleaseSemaphore(full, 1, NULL);
return 0;
}
int remove_item(buffer_item *item) {
WaitForSingleObject(full, INFINITE);
WaitForSingleObject(mutex, INFINITE);
if (buffer_pos <= 0) {
ReleaseSemaphore(mutex, 1, NULL);
ReleaseSemaphore(full, 1, NULL);
return -1;
}
*item = buffer[--buffer_pos];
ReleaseSemaphore(mutex, 1, NULL);
ReleaseSemaphore(empty, 1, NULL);
return 0;
}
DWORD WINAPI producer(void *param) {
int sleep_time = *(int *)param;
buffer_item item;
while (TRUE) {
/* sleep for a random amount of time */
Sleep(rand() % sleep_time * 1000);
/* generate a random item */
item = rand();
/* insert item into buffer */
if (insert_item(item) == -1) {
fprintf(stderr, "Error inserting item!\n");
} else {
printf("Producer produced item %d\n", item);
}
}
return 0;
}
DWORD WINAPI consumer(void *param) {
int sleep_time = *(int *)param;
buffer_item item;
while (TRUE) {
/* sleep for a random amount of time */
Sleep(rand() % sleep_time * 1000);
/* remove item from buffer */
if (remove_item(&item) == -1) {
fprintf(stderr, "Error removing item!\n");
} else {
printf("Consumer consumed item %d\n", item);
}
}
return 0;
}
阅读全文