使用Win32 API实现生产者消费者线程同步
Posted brucemengbm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Win32 API实现生产者消费者线程同步相关的知识,希望对你有一定的参考价值。
使用win32 API创建线程,创建信号量用于线程的同步
创建信号量
语法例如以下
HANDLE semophore; semophore = CreateSemaphore(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName);
CreateSemophore函数的原型例如以下:
HANDLE WINAPI CreateSemaphore( _In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,//属性 _In_ LONG lInitialCount,//初始值 _In_ LONG lMaximumCount,//最大值 _In_opt_ LPCTSTR lpName//信号量对象的名字 );函数返回一个指向信号量对象的句柄,是一个HANDLE对象
wait操作和signal操作
使用结构通常是这种
while(true){ WaitForSingleObject(semophore,INFINITE);//wait操作 //临界区 ReleaseSemaphore(semophore,1,NULL);//signal操作 }
两个函数的原型例如以下:
DWORD WaitForSingleObject( HANDLE hHandle,//句柄。能够指向信号量或者线程 DWORD dwMilliseconds//等待的毫秒数 ); BOOL ReleaseSemaphore( HANDLE hSemaphore,//句柄,指向信号量 LONG lReleaseCount,//给信号量添加值,通常是1 LPLONG lpPreviousCount//保存信号量之前的值的变量的指针 );
创建线程
HANDLE producer; //PRODUCER 线程运行这个函数 //pro_id 线程id producer = CreateThread(NULL, 0, PRODUCER, NULL, 0, &pro_id);//创建线程
函数原型
HANDLE WINAPI CreateThread( _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,//指向线程属性结构体的指针 _In_ SIZE_T dwStackSize,//栈的初始化大小,0表示使用默认的大小 _In_ LPTHREAD_START_ROUTINE lpStartAddress,//起始地址,也就是线程函数的指针 _In_opt_ LPVOID lpParameter,//线程函数參数的指针 _In_ DWORD dwCreationFlags,//控制创建的标志位,0表示线程创建后马上运行,CREATE_SUSPENDED表示新建为suspended状态,直到 ResumeThread 被调用时才运行。STACK_SIZE_PARAM_IS_A_RESERVATION,由dwStackSize 參数指定初始的保留栈的大小。不指定的话,dwStackSize指定提交的大小 _Out_opt_ LPDWORD lpThreadId//线程id的指针 );
生产者消费者线程同步代码例如以下
#include<Windows.h> #include<iostream> #define QUEUE_LENGTH 10 //缓冲区长度 HANDLE full_sem; //满信号量 HANDLE empty_sem; //空信号量 struct Msg { int i; };//消息结构 Msg MsgQueue[QUEUE_LENGTH]; //缓冲区 int head = 0;//队列头 int tail = 0;//队列尾 DWORD WINAPI CONSUMER(LPVOID lpParameter){//消费者线程 for (int i = 0;;i++){ WaitForSingleObject(full_sem, INFINITE);//wait操作 //WaitForSingleObject(mutex, INFINITE);//多个消费者须要加相互排斥信号量 int val = MsgQueue[head].i; head = (head + 1) % QUEUE_LENGTH; //ReleaseSemaphore(mutex, 1, NULL);//signal操作 std::cout << "CONSUMER : "<<val<< std::endl; ReleaseSemaphore(empty_sem, 1, NULL);//signal操作 } return 0; } DWORD WINAPI PRODUCER(LPVOID lpParameter){//生产者线程 for (int i = 0;; i++){ WaitForSingleObject(empty_sem, INFINITE); //WaitForSingleObject(mutex, INFINITE);//多个生产者须要加相互排斥信号量 MsgQueue[tail].i = i; tail=(tail+1) % QUEUE_LENGTH; //ReleaseSemaphore(mutex, 1, NULL); std::cout << "PRODUCER : " <<i<< std::endl; ReleaseSemaphore(full_sem, 1, NULL); } return 0; } int main(){ full_sem = CreateSemaphore(NULL, 0, QUEUE_LENGTH, NULL);//创建信号量 初始值为0,最大值为QUEUE_LENGTH empty_sem = CreateSemaphore(NULL,QUEUE_LENGTH,QUEUE_LENGTH,NULL); DWORD pro_id;//pid DWORD con_id; HANDLE producer = CreateThread(NULL, 0, PRODUCER, NULL, 0, &pro_id);//创建线程 //Sleep(1000);//展示堵塞 HANDLE consumer = CreateThread(NULL, 0, CONSUMER, NULL, 0, &con_id); WaitForSingleObject(producer, INFINITE); WaitForSingleObject(consumer, INFINITE);//等待线程运行完成 CloseHandle(producer); CloseHandle(consumer);//关闭内核对象 }
以上是关于使用Win32 API实现生产者消费者线程同步的主要内容,如果未能解决你的问题,请参考以下文章