等待队列数据推送的Windows c++线程
windows c++ thread waiting on queue data-push
程序设置如下:
有一个线程安全的队列类,一个线程在无限循环中向它推送数据,另一个线程在无限循环中从它弹出数据。我正试图想出一种方法来使用windows事件,或其他一些机制,使thread_1(下面),在无限while循环中等待,只有当队列深度大于或等于1时才迭代。
class thread-safe_Queue
{
public:
push();
pop();
};
DWORD thread_1()
{
while(1)
{
// wait for thread-safe queue to have data on it
// pop data off
// process data
}
}
DWORD thread_2()
{
while(1)
{
// when data becomes available, push data onto thread-safe queue
}
}
我想这可能会奏效。派生类Event并重载Process()函数。
#include <process.h> // Along with all the normal windows includes
//*********************************************
using namespace os;
Mutex globalQueueMutex;
class QueueReader : public Event
{
public:
virtual void Process()
{
// Lock the queue
Locker l(globalQueueMutex);
// pop data off
// process data
return; // queue will automatically unlock
}
};
QueueReader myQueueReader;
//*********************************************
// The queue writer would have functions like :
void StartQueueReader()
{
Thread(QueueReader::StartEventHandler, &myQueueReader);
}
void WriteToQueue()
{
Locker l(globalQueueMutex);
// write to the queue
myQueueReader.SignalProcess(); // tell reader to wake up
}
// When want to shutdown
void Shutdown()
{
myQueueReader.SignalShutdown();
}
下面是执行魔术的类。
namespace os {
// **********************************************************************
/// Windows implementation to spawn a thread.
static uintptr_t Thread (void (*StartAddress)(void *), void *ArgList)
{
return _beginthread(StartAddress, 0, ArgList);
}
// **********************************************************************
/// Windows implementation of a critical section.
class Mutex
{
public:
// Initialize section on construction
Mutex() { InitializeCriticalSection( &cs_ ); }
// Delete section on destruction
~Mutex() { DeleteCriticalSection( &cs_ ); }
// Lock it
void lock() { EnterCriticalSection( &cs_ ); }
// Unlock it
void unlock() { LeaveCriticalSection( &cs_ ); }
private:
CRITICAL_SECTION cs_;
}; // class Mutex
/// Locks/Unlocks a mutex
class Locker
{
public:
// Lock the mutex on construction
Locker( Mutex& mutex ): mutex_( mutex ) { mutex_.lock(); }
// Unlock on destruction
~Locker() { mutex_.unlock(); }
private:
Mutex& mutex_;
}; // class Locker
// **********************************************************************
// Windows implementation of event handler
#define ProcessEvent hEvents[0]
#define SetTimerEvent hEvents[1]
#define ShutdownEvent hEvents[2]
/// Windows implementation of events
class Event
{
/// Flag set when shutdown is complete
bool Shutdown;
/// Max time to wait for events
DWORD Timer;
/// The three events - process, reset timer, and shutdown
HANDLE hEvents[3];
public:
/// Timeout is disabled by default and Events assigned
Event( DWORD timer = INFINITE) : Timer(timer)
{
Shutdown = false;
ProcessEvent = CreateEvent( NULL,TRUE,FALSE,NULL );
SetTimerEvent = CreateEvent( NULL,TRUE,FALSE,NULL );
ShutdownEvent = CreateEvent( NULL,TRUE,FALSE,NULL );
}
/// Close the event handles
virtual ~Event()
{
CloseHandle(ProcessEvent);
CloseHandle(SetTimerEvent);
CloseHandle(ShutdownEvent);
}
/// os::Thread calls this to start the Event handler
static void StartEventHandler(void *pMyInstance)
{ ((Event *)pMyInstance)->EventHandler(); }
/// Call here to Change/Reset the timeout timer
void ResetTimer(DWORD timer) { Timer = timer; SetEvent(SetTimerEvent); }
/// Set the signal to shutdown the worker thread processing events
void SignalShutdown() { SetEvent(ShutdownEvent); while (!Shutdown) Sleep(30);}
/// Set the signal to run the process
void SignalProcess() { SetEvent(ProcessEvent); }
protected:
/// Overload in derived class to process events with worker thread
virtual void Process(){}
/// Override to process timeout- return true to terminate thread
virtual bool Timeout(){ return true;}
/// Monitor thread events
void EventHandler()
{
DWORD WaitEvents;
while (!Shutdown)
{
// Wait here, looking to be signaled what to do next
WaitEvents = WaitForMultipleObjects(3, hEvents, FALSE, Timer);
switch (WaitEvents)
{
// Process event - process event then reset for the next one
case WAIT_OBJECT_0 + 0:
Process();
ResetEvent(ProcessEvent);
break;
// Change timer event - see ResetTimer(DWORD timer)
case WAIT_OBJECT_0 + 1:
ResetEvent(SetTimerEvent);
continue;
// Shutdown requested so exit this thread
case WAIT_OBJECT_0 + 2:
Shutdown = true;
break;
// Timed out waiting for an event
case WAIT_TIMEOUT:
Shutdown = Timeout();
break;
// Failed - should never happen
case WAIT_FAILED:
break;
default:
break;
}
}
}
};
} // namespace os
这个怎么样(我假设您熟悉事件机制)
1。
thread_safe_Queue::push(something)
{
// lock the queue
...
// push object
// Signal the event
SetEvent(notification);
// unlock the queue
}
2。
thread_safe_Queue::pop(something)
{
WaitForSingleObject(notification);
// lock the queue
...
// get object
// reset the event
if (queue is empty)
ResetEvent(notification);
// unlock the queue
}
3。Thread_1只是尝试弹出对象并处理它。当某些东西被推送时,事件被启用,因此可以成功地调用pop
。否则它会在pop
中等待。实际上,您可以使用其他同步对象,如互斥锁或临界区,而不是在这种情况下的事件。
更新。外部事件:线程1:
void thread_1()
{
while(1)
{
WaitForSingleObject(notification);
if (!pop(object)) // pop should return if there are any objects left in queue
SetEvent(notification);
}
}
thread_2
void thread_2()
{
while(1)
{
// push the object and than signal event
ResetEvent(notification)
}
}
您可以使用命名事件。每个线程调用CreateEvent传递相同的名称。然后使用WaitForMultipleObjects等待与队列相关的事件或结束程序事件。pop线程将等待queue_has_data和end_program事件。push线程将等待data_available和end_program事件,并在将内容放入队列时设置queue_has_data事件。
相关文章:
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 在Linux for Windows上编译C++代码时出错
- 在Windows上用C++裁剪HBITMAP
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 当我编译webrtc服务器时,Windows上只支持clang-cl
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- Windows/Cygwin - 不能使用 pybind11 - 犯错误
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- 在Windows中以.exe的形式运行c++
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 无法在windows控制台中为C++程序提供必要的输入
- 在Windows中查找扬声器输出的当前音量级别
- Windows.h与GLFW.h的接口
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 在Linux和C++中的Windows上,散列字符串值会产生不同的输出
- Active Directory:从网络服务帐户下运行的Windows服务调用ADsOpenObject时失败
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 无法使用Qt Creator在Windows中构建yaml-cpp