windows 使用关键段和条件变量实现的生产者和消费者线程同步
来源:互联网 发布:淘宝上买二手电脑配件 编辑:程序博客网 时间:2024/04/28 10:02
关键段比较简单,调用函数如下:
VOID InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection );//初始化一个关键代码段
VOID EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection);//获取关键代码段的访问权
VOID LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection);//释放关键代码段的访问权
VOID DeleteCriticalSection( LPCRITICAL_SECTION lpCriticalSection);//删除关键代码段
条件变量的介绍:
Condition variables are synchronization primitives that enable threads to wait until a particular condition occurs. Condition variables are user-mode objects that cannot be shared across processes.
Condition variables enable threads to atomically release a lock and enter the sleeping state. They can be used with critical sections or slim reader/writer (SRW) locks. Condition variables support operations that "wake one" or "wake all" waiting threads. After a thread is woken, it re-acquires the lock it released when the thread entered the sleeping state.
Windows Server 2003 and Windows XP: Condition variables are not supported.
The following are the condition variable functions.
The following pseudocode demonstrates the typical usage pattern of condition variables.
CRITICAL_SECTION CritSection;CONDITION_VARIABLE ConditionVar;void PerformOperationOnSharedData(){ EnterCriticalSection(&CritSection); // Wait until the predicate is TRUE while( TestPredicate() == FALSE ) { SleepConditionVariableCS(&ConditionVar, &CritSection, INFINITE); } // The data can be changed safely because we own the critical // section and the predicate is TRUE ChangeSharedData(); LeaveCriticalSection(&CritSection); // If necessary, signal the condition variable by calling // WakeConditionVariable or WakeAllConditionVariable so other // threads can wake}
The following code implements a producer/consumer queue. The queue is represented as a bounded circular buffer, and is protected by a critical section. The code uses two condition variables: one used by producers (BufferNotFull
) and one used by consumers (BufferNotEmpty
).
The code calls the InitializeConditionVariable function to create the condition variables. The consumer threads call theSleepConditionVariableCS function to wait for items to be added to the queue and theWakeConditionVariable function to signal the producer that it is ready for more items. The producer threads callSleepConditionVariableCS to wait for the consumer to remove items from the queue andWakeConditionVariable to signal the consumer that there are more items in the queue.
#include <windows.h>#include <stdlib.h>#include <stdio.h>#define BUFFER_SIZE 10#define PRODUCER_SLEEP_TIME_MS 500#define CONSUMER_SLEEP_TIME_MS 2000LONG Buffer[BUFFER_SIZE];LONG LastItemProduced;ULONG QueueSize;ULONG QueueStartOffset;ULONG TotalItemsProduced;ULONG TotalItemsConsumed;CONDITION_VARIABLE BufferNotEmpty;CONDITION_VARIABLE BufferNotFull;CRITICAL_SECTION BufferLock;BOOL StopRequested;DWORD WINAPI ProducerThreadProc (PVOID p){ ULONG ProducerId = (ULONG)(ULONG_PTR)p; while (true) { // Produce a new item. Sleep (rand() % PRODUCER_SLEEP_TIME_MS); ULONG Item = InterlockedIncrement (&LastItemProduced); EnterCriticalSection (&BufferLock); while (QueueSize == BUFFER_SIZE && StopRequested == FALSE) { // Buffer is full - sleep so consumers can get items. SleepConditionVariableCS (&BufferNotFull, &BufferLock, INFINITE); } if (StopRequested == TRUE) { LeaveCriticalSection (&BufferLock); break; } // Insert the item at the end of the queue and increment size. Buffer[(QueueStartOffset + QueueSize) % BUFFER_SIZE] = Item; QueueSize++; TotalItemsProduced++; printf ("Producer %u: item %2d, queue size %2u\r\n", ProducerId, Item, QueueSize); LeaveCriticalSection (&BufferLock); // If a consumer is waiting, wake it. WakeConditionVariable (&BufferNotEmpty); } printf ("Producer %u exiting\r\n", ProducerId); return 0;}DWORD WINAPI ConsumerThreadProc (PVOID p){ ULONG ConsumerId = (ULONG)(ULONG_PTR)p; while (true) { EnterCriticalSection (&BufferLock); while (QueueSize == 0 && StopRequested == FALSE) { // Buffer is empty - sleep so producers can create items. SleepConditionVariableCS (&BufferNotEmpty, &BufferLock, INFINITE); } if (StopRequested == TRUE && QueueSize == 0)//等消费完再退出 { LeaveCriticalSection (&BufferLock); break; } // Consume the first available item. LONG Item = Buffer[QueueStartOffset]; QueueSize--; QueueStartOffset++; TotalItemsConsumed++; if (QueueStartOffset == BUFFER_SIZE) { QueueStartOffset = 0; } printf ("Consumer %u: item %2d, queue size %2u\r\n", ConsumerId, Item, QueueSize); LeaveCriticalSection (&BufferLock); // If a producer is waiting, wake it. WakeConditionVariable (&BufferNotFull); // Simulate processing of the item. Sleep (rand() % CONSUMER_SLEEP_TIME_MS); } printf ("Consumer %u exiting\r\n", ConsumerId); return 0;}int main ( void ){ InitializeConditionVariable (&BufferNotEmpty); InitializeConditionVariable (&BufferNotFull); InitializeCriticalSection (&BufferLock); DWORD id; HANDLE hProducer1 = CreateThread (NULL, 0, ProducerThreadProc, (PVOID)1, 0, &id); HANDLE hConsumer1 = CreateThread (NULL, 0, ConsumerThreadProc, (PVOID)1, 0, &id); HANDLE hConsumer2 = CreateThread (NULL, 0, ConsumerThreadProc, (PVOID)2, 0, &id); puts ("Press enter to stop..."); getchar(); EnterCriticalSection (&BufferLock); StopRequested = TRUE; LeaveCriticalSection (&BufferLock); WakeAllConditionVariable (&BufferNotFull); WakeAllConditionVariable (&BufferNotEmpty); WaitForSingleObject (hProducer1, INFINITE); WaitForSingleObject (hConsumer1, INFINITE); WaitForSingleObject (hConsumer2, INFINITE); printf ("TotalItemsProduced: %u, TotalItemsConsumed: %u\r\n", TotalItemsProduced, TotalItemsConsumed); return 0;}
- windows 使用关键段和条件变量实现的生产者和消费者线程同步
- 线程同步:条件变量实现生产者消费者模型
- 线程同步2 ------ 条件变量实现“生产者-消费者”续
- Linux多线程,生产者消费者算法和条件变量的使用
- 线程同步:生产者和消费者的问题
- 多线程---使用ManualResetEvent来控制线程间的同步(实现了消费者和生产者模式)
- 互斥量和条件变量实现生产者消费者模型
- 【Linux】线程总结:线程同步 -互斥锁,条件变量,信号量实现多生产者多消费者模型
- 使用条件变量实现生产者消费者模式
- 线程同步生产者和消费者c和java不同实现
- 并发编程(一): POSIX 使用互斥量和条件变量实现生产者/消费者问题
- 使用信号量和关键区来实现生产者消费者
- 生产者和消费者线程实现
- java实现线程同步一个生产者和一个消费者
- 【线程的同步与互斥 (互斥量 条件变量 信号量)】生产者与消费者模型
- 线程同步中的“生产者和消费者”模式
- java实现的生产者和消费者问题-涉及线程同步与通信
- linux线程同步:互斥量和条件变量的使用
- 十四周项目一(2)
- 解决Windows 2003系统远程会话30分钟自动关闭
- 软件开发中 常见英文文档 缩写(转)
- 精通 CSS+DIV 网页样式与布局 62
- 1003. 我要通过!(20)
- windows 使用关键段和条件变量实现的生产者和消费者线程同步
- CC2530 串口打印log
- Your project path contains non-ASCII characters
- MFC的程序必须安装.Net Framework才能运行么?
- 《Java源码解析》之NIO的Selector机制(Part2:SelectableChannel.register(Selector sel, int ops))
- 接收后台返回的文本内容呈现换行的样式
- egret 性能测试
- 精通 CSS+DIV 网页样式与布局 63
- HTML5 拖拉上传文件