- 浏览: 26863 次
- 性别:
- 来自: 深圳
最新评论
// BlockingQueue.h: interface for the CBlockingQueue class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_BLOCKINGQUEUE_H__E6C614E8_4A5D_4D18_A38D_845018DA75B6__INCLUDED_) #define AFX_BLOCKINGQUEUE_H__E6C614E8_4A5D_4D18_A38D_845018DA75B6__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include <windows.h> #include <LIST> #include <vector> #include <STRING> using namespace std; class CBlockingQueue { public: CBlockingQueue(int size); virtual ~CBlockingQueue(); private: CBlockingQueue(); HANDLE m_MssageNullEvent; HANDLE m_synSignal; int m_size; list<string> m_msgs; public: string Dequeue(); void Enqueue(string msg); }; #endif // !defined(AFX_BLOCKINGQUEUE_H__E6C614E8_4A5D_4D18_A38D_845018DA75B6__INCLUDED_)
// BlockingQueue.cpp: implementation of the CBlockingQueue class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "BlockingQueue.h" #include <afxcom_.h> ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CBlockingQueue::CBlockingQueue() { } CBlockingQueue::CBlockingQueue(int ssize) { m_size=ssize; m_synSignal=CreateSemaphore(NULL,1,1,"m_synSignal"); m_MssageNullEvent=CreateEvent(NULL,TRUE,TRUE,"m_MssageNullEvent"); } CBlockingQueue::~CBlockingQueue() { } string CBlockingQueue::Dequeue() { string msg=""; WaitForSingleObject(m_synSignal,INFINITE); while(0==m_msgs.size()) { bool breset=ResetEvent(m_MssageNullEvent); ReleaseSemaphore(m_synSignal,1,NULL); DWORD nret=WaitForSingleObject(m_MssageNullEvent,INFINITE); //ASSERT(WAIT_TIMEOUT!=); } string temp=*m_msgs.begin(); m_msgs.pop_front(); SetEvent(m_MssageNullEvent); ReleaseSemaphore(m_synSignal,1,NULL); return temp; } void CBlockingQueue::Enqueue(string msg) { WaitForSingleObject(m_synSignal,INFINITE); int a=m_msgs.size(); while(m_size==m_msgs.size()) { bool bret= ResetEvent(m_MssageNullEvent); ReleaseSemaphore(m_synSignal,1,NULL); DWORD nret= WaitForSingleObject(m_MssageNullEvent,INFINITE); } m_msgs.push_back(msg); ReleaseSemaphore(m_synSignal,1,NULL); if (1==m_msgs.size()) SetEvent(m_MssageNullEvent); }
以上不具有普遍性,更合理的设计如下:
将 同步内核对象抽象出来 成为 CMonitor
// Monitor.h: interface for the CMonitor class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_MONITOR_H__26A4800D_6F3C_41BF_97AC_1D20860517AC__INCLUDED_) #define AFX_MONITOR_H__26A4800D_6F3C_41BF_97AC_1D20860517AC__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include <windows.h> class CMonitor { public: CMonitor(); virtual ~CMonitor(); private: HANDLE m_h[2]; DWORD m_lastThreadId; public: void wait(DWORD timeout); bool pulse(); void Enter(); void Exit(); }; #endif // !defined(AFX_MONITOR_H__26A4800D_6F3C_41BF_97AC_1D20860517AC__INCLUDED_)
// Monitor.cpp: implementation of the CMonitor class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Monitor.h" #include <exception> ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CMonitor::CMonitor() { m_h[0]=CreateEvent(NULL,TRUE,TRUE,"h1"); m_h[1]=CreateEvent(NULL,TRUE,TRUE,"h2"); m_lastThreadId=0; } CMonitor::~CMonitor() { } void CMonitor::Enter() { m_lastThreadId=::GetCurrentThreadId(); WaitForSingleObject(m_h[0],INFINITE);//ResetEvent(); } void CMonitor::Exit() { m_lastThreadId=NULL; SetEvent(m_h[0]); SetEvent(m_h[1]); } bool CMonitor::pulse() { if (!(m_lastThreadId!=NULL || m_lastThreadId!=::GetCurrentThreadId())) { throw exception("The wait could only be excuted by the monitor owner!"); } SetEvent(m_h[1]); return true; } void CMonitor::wait( DWORD timeout ) { if (!(m_lastThreadId!=NULL || m_lastThreadId!=::GetCurrentThreadId())) { throw exception("The wait could only be excuted by the monitor owner!"); } m_lastThreadId=NULL; ResetEvent(m_h[1]); WaitForSingleObject(m_h[1],timeout); SetEvent(m_h[0]); }
那么新的 BlockingQueue代码如下:
// BlockingQueue.h: interface for the CBlockingQueue class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_BLOCKINGQUEUE_H__E6C614E8_4A5D_4D18_A38D_845018DA75B6__INCLUDED_) #define AFX_BLOCKINGQUEUE_H__E6C614E8_4A5D_4D18_A38D_845018DA75B6__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include <windows.h> #include <LIST> #include <vector> #include <STRING> #include "Monitor.h" using namespace std; class CBlockingQueue { public: CBlockingQueue(int size); virtual ~CBlockingQueue(); private: CBlockingQueue(); int m_size; list<string> m_msgs; CMonitor m_monitor; public: string Dequeue(); void Enqueue(string msg); }; #endif // !defined(AFX_BLOCKINGQUEUE_H__E6C614E8_4A5D_4D18_A38D_845018DA75B6__INCLUDED_)
// BlockingQueue.cpp: implementation of the CBlockingQueue class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "BlockingQueue.h" #include <afxcom_.h> ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CBlockingQueue::CBlockingQueue() { } CBlockingQueue::CBlockingQueue(int ssize) { m_size=ssize; } CBlockingQueue::~CBlockingQueue() { } string CBlockingQueue::Dequeue() { string msg=""; m_monitor.Enter(); { while(0==m_msgs.size()) { m_monitor.wait(INFINITE); } msg=*m_msgs.begin(); m_msgs.pop_front(); if ((m_size-1)==m_msgs.size()) m_monitor.pulse(); } m_monitor.Exit(); return msg; } void CBlockingQueue::Enqueue(string msg) { m_monitor.Enter(); { int a=m_msgs.size(); while(m_size==m_msgs.size()) { m_monitor.wait(INFINITE); } m_msgs.push_back(msg); if (1==m_msgs.size()) m_monitor.pulse(); } m_monitor.Exit(); }
发表评论
-
网络编程——一些思考
2013-05-09 15:07 5281. 在学习网络编程的时候,我通过网上的了解,买了不少书, ... -
centos中编译log4cxx
2013-03-18 10:10 1577log4cxx-0.10.0日志中文乱码 log4cxx ... -
linux在用户程序中如何向操作系统发送按键事件
2013-01-23 19:09 2559转自:http://blog.csdn.net/xian ... -
为什么linux下多线程编程,每次执行结果都不一样
2013-01-03 21:41 1208#include <pthread.h> ... -
27种设计模式C++实现——单例模式
2012-09-25 22:02 01. 单例模式 -
27种设计模式C++实现——原始模型模式
2012-09-25 22:01 7301. 克隆接口 2. 具体实现者类 -
27种设计模式C++实现——建造者模式
2012-09-25 21:59 10571. 指导者类 2. 抽象建造者类 3. 具体建造者类 ... -
27种设计模式C++实现——抽象工厂
2012-09-25 21:57 12041. 抽象产品类 2. 具体产品类 3. 抽象工厂 4. ... -
27种设计模式C++实现——工厂方法
2012-09-25 21:55 6851. 抽象产品类 2. 具体产品类 3. 工厂接口 4. ... -
27种设计模式C++实现——简单工厂
2012-09-25 21:54 684简单工厂 1. 抽象产品类 2. 具体产品类 3. ... -
面向对象编程<继承覆盖>之——C++
2012-09-23 21:39 703C++面向对象继承,虚方法,类似于指针..... ... -
windows进程同步
2012-09-21 15:40 9341. 进程同步的思想很简单 操作系统所有进程,都是内核 ... -
C内存对齐详解
2012-09-18 17:05 626一、什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空 ... -
C++
2012-09-18 11:30 01. 学会数据分层,例如串口指令,与硬件业务分离 2. 学会 ... -
Java与C++内存回收浅析
2012-09-17 11:12 0java与C++内存回收浅析 内存分配结构 ... -
函数如何返回struct或class对象
2012-07-16 16:28 588所有的C、C++教科书都警 ... -
MFC Activex与JavaScript的接口交互
2012-06-18 15:06 1252在Activex的应用中与网页的JavaScript的交互必不 ...
相关推荐
《C++实现的跨平台BlockingQueue详解》 在软件开发中,线程间的通信和同步是必不可少的部分。Java中的`BlockingQueue`是一个高效且常用的并发工具类,它提供了线程安全的数据结构,允许一个线程放入元素,而另一个...
它可能包含了上述某一种或多种队列的实现,例如用C++、Java或其他编程语言实现的简单队列、阻塞队列、并发队列等。具体的实现细节需要查看源代码才能得知。 在实际应用中,队列常被用于任务调度、消息传递、网络...
在C++环境中,`BlockingQueue.h`可能是一个自定义实现的阻塞队列头文件。它可能会包含如下内容: 1. **模板类定义**:定义一个模板类`BlockingQueue<T>`,其中`T`代表队列中元素的类型。 2. **数据成员**:使用`std...
在这个例子中,我们看到如何在Linux环境下使用C++和POSIX线程库(pthread)中的条件变量(condition variables)来实现阻塞队列。 首先,我们需要包含必要的头文件,并定义一个名为`BlockingQueue`的类。这个类包含了...
Java的`BlockingQueue`接口和Python的`queue`模块提供了现成的实现。 4. **管程(Monitor)**:Java中的`synchronized`关键字和`wait()`, `notify()`, `notifyAll()`方法其实就是一个简单的管程实现,它提供了线程...
在Java中,`java.util.concurrent`包下的`BlockingQueue`接口及其实现类如`LinkedBlockingQueue`是很好的选择。 在实际应用中,多线程队列和COM组件的结合能提高系统的并发性能,降低资源消耗,同时简化并发编程的...
Java的内存管理主要依赖于垃圾收集机制,但在操作系统层面,我们可能需要实现类似C++的`malloc`和`free`函数,或者理解Java的堆和栈内存结构,以及如何有效地分配和回收内存。 3. **生产者消费者问题**:这是一个...
本资源"实现多线程编程.rar"显然是针对Java、C语言、C++、C以及JSP开发者的一份珍贵内部资料,它涵盖了多线程编程的核心概念和实践技巧。 1. **多线程定义**:多线程是指一个程序中可以同时执行多个线程(或称为轻...
生产者与消费者问题是一个经典的多线程同步问题,在计算机科学和软件工程中有着广泛的应用。...在实际应用中,可以根据具体需求选择不同的实现方式,例如Java的`BlockingQueue`或C++的`std::condition_variable`。
在Java中,可以使用`BlockingQueue`接口来实现生产者-消费者模式,它已经内置了线程安全的队列操作。生产者可以使用`offer()`方法添加元素,消费者则用`take()`方法取出元素,这两个方法会自动处理等待和唤醒操作。 ...
而在C++中,可以使用`std::condition_variable`和`std::mutex`配合自定义的队列来实现。 具体实现时,生产者线程会执行以下步骤: 1. 生产数据。 2. 获取队列的写锁(互斥锁)。 3. 检查队列是否已满。如果已满,...
在Java或C++等编程语言中,我们可以利用多线程来实现“生产者消费者”模式,这是一个经典的并发问题。这个模式涉及到两个主要角色:生产者(Producer)和消费者(Consumer),它们共享一个有限大小的缓冲区作为临界...
在Java中,可以使用`BlockingQueue`实现线程间的通信。 五、死锁、活锁与饥饿 1. 死锁:两个或更多线程相互等待对方释放资源,导致无法继续执行。避免死锁的关键在于遵循资源的有序分配和避免循环等待。 2. 活锁...
Java中的BlockingQueue,C++中的`std::queue`配合`condition_variable`,Python的`Queue`模块都是实现这一模式的例子。 4. **线程安全**:讲解如何编写线程安全的代码,避免数据不一致和资源竞争。这可能涉及到无锁...
3. **并发容器**:Java并发集合框架包括`ConcurrentHashMap`、`CopyOnWriteArrayList`、`BlockingQueue`等,它们设计时考虑了并发安全,能有效避免并发问题。 4. **Java内存模型**:JMM(Java Memory Model)规定了...
在Java中,可以利用`java.util.concurrent`包下的`BlockingQueue`;在C++中,可以使用Boost库的`message_queue`。 7. **示例代码分析**:压缩包中的文件"演示线程消息发送"很可能包含了具体的操作示例,可能包括...
3. **线程通信**:例如,使用Java的`BlockingQueue`进行线程间的数据传递,或者Python的`queue`模块,实现线程间的协作。 4. **线程优先级**:在某些系统中,线程有优先级概念,高优先级线程会先于低优先级线程执行...
这个测试可能涵盖各种同步策略,如使用`synchronized`关键字保护共享数据,或者使用`BlockingQueue`来实现线程间的通信和同步。 总结,多线程批量线程同步解决方案涵盖了多种技术,从基本的互斥量到复杂的线程池,...
8. **线程间的通信(Thread Communication)**:Java 提供了多种方式实现线程间的通信,如 wait(), notify() 和 notifyAll(),以及 BlockingQueue 等高级接口,它们使得线程能够协调执行,避免不必要的等待。...