问题描述
我正在为Linux平台实现多线程C ++程序,在这里我需要类似于WaitForMultipleObjects()的功能.
在寻找解决方案时,我观察到有一些文章用示例描述了如何在Linux中实现WaitForMultipleObjects()功能,但是这些示例并不满足我必须支持的情况.
在我的情况下,情况非常简单.我有一个守护进程,在该进程中主线程向外部世界(例如,向DLL)公开方法/回调.DLL的代码不在我的控制之下.相同的主线程创建一个新线程线程1".线程1必须执行某种无限循环,在该循环中,它将等待关闭事件(守护程序关闭),或者将等待通过上述公开的方法/回调发出信号的数据可用事件.
简而言之,线程将在等待关闭事件和数据可用事件时等待,如果发出了关闭事件信号,则等待将满足,循环将中断;或者,如果发出了数据可用事件,则线程还将等待,并且线程将开展业务处理.
在 Windows 中,它看起来非常简单.以下是针对我的方案的基于MS Windows的伪代码.
//**主线程**//加载DLLLoadLibrary(某些DLL")//创建一个新线程hThread1 = __beginthreadex(...,& ThreadProc,...)//由DLL调用的主线程(在上面的描述中提到)中的回调无效的Callbackfunc(数据){qdata.push(data);SetEvent(s_hDataAvailableEvent);}无效的OnShutdown(){SetEvent(g_hShutdownEvent);WaitforSingleObject(hThread1,...,INFINITE);//在这里清理}//**线程1 **unsigned int WINAPI ThreadProc(无效* pObject){一会儿(true){处理hEvents [2];hEvents [0] = g_hShutdownEvent;hEvents [1] = s_hDataAvailableEvent;//3rd参数设置为FALSE,这意味着如果发出任何一个对象的状态信号,则等待应该满足.dwEvent = WaitForMultipleObjects(2,hEvents,FALSE,INFINITE);开关(dwEvent){案例WAIT_OBJECT_0 + 0://设置关机事件,中断循环返回0;案例 WAIT_OBJECT_0 + 1://在这里做业务处理休息;默认://错误处理}}}
我想在Linux上实现相同的功能.根据我对Linux的理解,它具有完全不同的机制,需要我们注册信号.如果终止信号到达,则该进程将知道即将关闭,但在此之前,必须等待正在运行的线程正常关闭.
在Linux中执行此操作的正确方法是使用条件变量.尽管这与Windows中的 WaitForMultipleObjects
不同,但您将获得相同的功能.
使用两个 bool
来确定是否有可用数据或必须进行关机.然后使关闭功能和数据功能都相应地设置布尔值,并向条件变量发出信号.
#include< pthread.h>pthread_cond_t cv = PTHREAD_COND_INITIALIZER;pthread_mutex_t互斥锁= PTHREAD_MUTEX_INITIALIZER;pthread_t hThread1;//这在Linux中并不是一个好名字,//最好使用"tid1"行,但对于//比较的缘故,我保留了这个bool shutdown_signalled;bool data_available;无效的OnShutdown(){//...关机行为...pthread_mutex_lock(& mutex);shutdown_signalled = true;pthread_mutex_unlock(& mutex);pthread_cond_signal(&cv);}无效的Callbackfunc(...){//...需要做什么...pthread_mutex_lock(& mutex);data_available = true;pthread_mutex_unlock(& mutex);pthread_cond_signal(& cv);}无效* ThreadProc(无效* args){while(true){pthread_mutex_lock(& mutex);while(!(shutdown_signalled || data_available)){//只要没有可用数据就等待,然后关闭//尚未发出信号pthread_cond_wait(& cv,& mutex);}如果(data_available){//处理数据data_available = false;}如果(shutdown_signalled){//执行关机pthread_mutex_unlock(& mutex);返回NULL;}pthread_mutex_unlock(& mutex);//您也许可以放开解锁//在ifs之前,idk代码的详细信息}}int main(无效){shutdown_signalled = false;data_available = false;pthread_create(& hThread1,& ThreadProc,...);pthread_join(hThread1,NULL);//...}
我知道Windows也具有条件变量,因此这看起来应该不太陌生.我不知道Windows对它们有什么规则,但是在POSIX平台上, wait
必须位于 while
循环内,因为可能会发生虚假唤醒"./p>
I am implementing multithreaded C++ program for Linux platform where I need a functionality similar to WaitForMultipleObjects().
While searching for the solution I observed that there are articles that describe how to achieve WaitForMultipleObjects() functionality in Linux with examples but those examples does not satisfy the scenario that I have to support.
The scenario in my case is pretty simple. I have a daemon process in which the main thread exposes a method/callback to the outside world for example to a DLL. The code of the DLL is not under my control. The same main thread creates a new thread "Thread 1". Thread 1 has to execute kind of an infinite loop in which it would wait for a shutdown event (daemon shutdown) OR it would wait on the data available event being signaled through the exposed method/callback mentioned above.
In short the thread would be waiting on shutdown event and data available event where if shutdown event is signaled the wait would satisfy and the loop would be broken or if data available event is signaled then also wait would satisfy and thread would do business processing.
In windows, it seems very straight forward. Below is the MS Windows based pseudo code for my scenario.
//**Main thread**
//Load the DLL
LoadLibrary("some DLL")
//Create a new thread
hThread1 = __beginthreadex(..., &ThreadProc, ...)
//callback in main thread (mentioned in above description) which would be called by the DLL
void Callbackfunc(data)
{
qdata.push(data);
SetEvent(s_hDataAvailableEvent);
}
void OnShutdown()
{
SetEvent(g_hShutdownEvent);
WaitforSingleObject(hThread1,..., INFINITE);
//Cleanup here
}
//**Thread 1**
unsigned int WINAPI ThreadProc(void *pObject)
{
while (true)
{
HANDLE hEvents[2];
hEvents[0] = g_hShutdownEvent;
hEvents[1] = s_hDataAvailableEvent;
//3rd parameter is set to FALSE that means the wait should satisfy if state of any one of the objects is signaled.
dwEvent = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
switch (dwEvent)
{
case WAIT_OBJECT_0 + 0:
// Shutdown event is set, break the loop
return 0;
case WAIT_OBJECT_0 + 1:
//do business processing here
break;
default:
// error handling
}
}
}
I want to implement the same for Linux. According to my understanding when it would come to Linux, it has totally different mechanism where we need to register for signals. If the termination signal arrives, the process would come to know that it is about to shutdown but before that it is necessary for the process to wait for the running thread to gracefully shutdown.
The correct way to do this in Linux would be using condition variables. While this is not the same as WaitForMultipleObjects
in Windows, you will get the same functionality.
Use two bool
s to determine whether there is data available or a shutdown must occur.Then have the shutdown function and the data function both set the bools accordingly, and signal the condition variable.
#include <pthread.h>
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_t hThread1; // this isn't a good name for it in linux, you'd be
// better with something line "tid1" but for
// comparison's sake, I've kept this
bool shutdown_signalled;
bool data_available;
void OnShutdown()
{
//...shutdown behavior...
pthread_mutex_lock(&mutex);
shutdown_signalled = true;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cv);
}
void Callbackfunc(...)
{
// ... whatever needs to be done ...
pthread_mutex_lock(&mutex);
data_available = true;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cv);
}
void *ThreadProc(void *args)
{
while(true){
pthread_mutex_lock(&mutex);
while (!(shutdown_signalled || data_available)){
// wait as long as there is no data available and a shutdown
// has not beeen signalled
pthread_cond_wait(&cv, &mutex);
}
if (data_available){
//process data
data_available = false;
}
if (shutdown_signalled){
//do the shutdown
pthread_mutex_unlock(&mutex);
return NULL;
}
pthread_mutex_unlock(&mutex); //you might be able to put the unlock
// before the ifs, idk the particulars of your code
}
}
int main(void)
{
shutdown_signalled = false;
data_available = false;
pthread_create(&hThread1, &ThreadProc, ...);
pthread_join(hThread1, NULL);
//...
}
I know windows has condition variables as well, so this shouldn't look too alien. I don't know what rules windows has about them, but on a POSIX platform the wait
needs to be inside of a while
loop because "spurious wakeups" can occur.
这篇关于C ++:Linux平台上的线程同步方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!