700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 【操作系统】多线程 生产者——消费者同步与互斥代码实现

【操作系统】多线程 生产者——消费者同步与互斥代码实现

时间:2022-01-30 22:28:18

相关推荐

【操作系统】多线程 生产者——消费者同步与互斥代码实现

简述:

两进程同步关系,有两个信号量,一个empty一个full。

假设产品缓冲区大小为n,则初值empty=n,full=0。

前操作(生产者):

P(empty)

V(full)

后操作(消费者):

P(full)

P(empty)

如果需要互斥访问缓冲区的话,要保证临界区代码尽量小,且需要避免死锁。

前操作(生产者):

P(empty)

P(mutex)

V(mutex)

V(full)

后操作(消费者):

P(full)

P(mutex)

V(mutex)

P(empty)


代码实现:

#include <stdio.h>#include <windows.h>/* 互斥与同步 */#define N 10// 缓存区大小#define COUNT 10// 模拟次数权重(=总执行次数/生产者线程数/消费者线程数/2)#define P_TIME 100// 生产一个产品时间#define C_TIME 50// 消耗一个产品时间#define P_COUNT 5// 生产者线程数量#define C_COUNT 3// 消费者线程数量HANDLE mutex = CreateMutex(NULL, FALSE, NULL);// 定义互斥量HANDLE empty = CreateSemaphore(NULL, N, N, NULL);// 缓冲区中空槽数信号量HANDLE full = CreateSemaphore(NULL, 0, N, NULL);// 缓冲区中满槽数信号量int buffer[N];// 有N个槽数的缓冲区buffer[N],并实现循环缓冲队列int front = 0;// 定义头指针int rear = 0;// 定义尾指针DWORD WINAPI producer(LPVOID lpParameter);// 生产者线程函数DWORD WINAPI consumer(LPVOID lpParameter);// 消费者线程函数void myPrint();// 输出缓冲区示意数组int main(){HANDLE p_thread[P_COUNT];// 生产者线程数组HANDLE c_thread[C_COUNT];// 消费者线程数组HANDLE handle[P_COUNT + C_COUNT];// 线程数组for (int i = 0; i < P_COUNT; i++){do{p_thread[i] = CreateThread(NULL, 0, producer, NULL, 0, NULL);// 创建生产者线程} while (!p_thread[i]);// 创建失败则重新创建handle[i] = p_thread[i];// 将生产者线程放置线程数组中}for (int i = 0; i < C_COUNT; i++){do{c_thread[i] = CreateThread(NULL, 0, consumer, NULL, 0, NULL);// 创建消费者线程} while (!c_thread[i]);// 创建失败则重新创建handle[P_COUNT + i] = c_thread[i];// 将消费者线程放置线程数组中}WaitForMultipleObjects(P_COUNT + C_COUNT, handle, TRUE, INFINITE);// 等待线程运行完毕return 0;}/* 生产者线程函数 */DWORD WINAPI producer(LPVOID lpParameter){int i = 0;while (i < COUNT * C_COUNT){WaitForSingleObject(empty, INFINITE);// 如果该槽没有产品=>P(empty)WaitForSingleObject(mutex, INFINITE);// 进入临界区,访问缓冲区临界资源=>P(mutex)buffer[front] = 1;// 生产产品front = (front + 1) % N;// 指针移动i++;Sleep(P_TIME);// 产品生产时间printf("生产产品\n");myPrint();// 打印演示ReleaseMutex(mutex);// 退出临界区=>V(mutex)ReleaseSemaphore(full, 1, NULL);// 满槽记录=>V(full)}return 0;}/* 消费者线程函数 */DWORD WINAPI consumer(LPVOID lpParameter){int i = 0;while (i < COUNT * P_COUNT){WaitForSingleObject(full, INFINITE);// 如果该槽存在产品=>P(full)WaitForSingleObject(mutex, INFINITE);// 进入临界区,访问缓冲区临界资源=>P(mutex)buffer[rear] = 0;// 消耗产品rear = (rear + 1) % N;// 指针移动i++;Sleep(C_TIME);// 产品消耗时间printf("消费产品\n");myPrint();// 打印演示ReleaseMutex(mutex);// 退出临界区=>V(mutex)ReleaseSemaphore(empty, 1, NULL);// 空槽记录=>V(empty)}return 0;}/* 输出缓冲区示意数组 */void myPrint(){printf("缓冲区示意数组:");for (int i = 0; i < N; i++){printf("%d ", buffer[i]);// 打印缓冲区数组}printf("\n");}


运行截图:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。