[英]condition_variable::wait_for method not returning - even after the timeout
I come from C# coding experience; 我来自C#编码经验; I am beginning to learn C++ and make use of boost libraries for threading. 我开始学习C ++,并利用Boost库进行线程化。 I wrote the following class - trying to execute a member function as a thread. 我编写了以下类-尝试将成员函数作为线程执行。 Writing the following simple code, i would expect the while loop inside the thread function to execute every second. 编写以下简单代码,我希望线程函数内的while循环每秒执行一次。
#include <boost/chrono/chrono.hpp>
#include <boost/thread/thread.hpp>
#include <iostream>
using namespace boost;
class MyClassWithThread : public boost::enable_shared_from_this<MyClassWithThread>
{
mutex muThreadControl;
condition_variable cvThreadControl;
bool threadToBeStopped = false;
void ThreadFunction()
{
std::cout << "Beginning the Thread" << std::endl;
while(true)
{
bool endIOThread = false;
std::cout << "\nChecking if Thread to be stopped: ";
{
boost::mutex::scoped_lock lock(muThreadControl);
endIOThread = cvThreadControl.wait_for(lock,
boost::chrono::seconds(1),
[this]{return threadToBeStopped;} ) == cv_status::no_timeout;
std::cout << endIOThread << std::endl
}
}
std::cout << "Exiting the Thread" << std::endl;
}
public:
thread threadRunner;
MyClassWithThread()
{
threadRunner = thread(&MyClassWithThread::ThreadFunction, this);
}
};
int main(int argc, char* argv[])
{
MyClassWithThread myclassWithThread;
myclassWithThread.threadRunner.join();
return 0;
}
To build on Linux: 要在Linux上构建:
g++ -std=c++11 -pthread cond-wait-test.cpp -o cond-wait-test -lboost_system -lboost_thread -lboost_chrono
However, when i execute the code, all i notice is that the thread execution is blocked at the call to wait_for method; 但是,当我执行代码时,我注意到的是线程的执行在调用wait_for方法时被阻塞了。 forever. 永远。 despite the timeout period. 尽管有超时时间。 Further, the resource monitor of the system shows a processor core is being 100% utilized. 此外,系统的资源监视器显示处理器核心已被100%利用。
Could anyone please explain whats happening in the code? 谁能解释一下代码中发生了什么?
As suggested by @Zan Lynx, the culprit was #pragma pack statement. 正如@Zan Lynx所建议的,罪魁祸首是#pragma pack语句。 I initially used only #pragma pack(1) to byte align some structures. 最初,我仅使用#pragma pack(1)对某些结构进行字节对齐。 This affected many of mutex structures to 1 byte alignment. 这将许多互斥锁结构影响到1字节对齐。
I changed the #pragma pack(1) statements to #pragma pack(push, 1) #pragma pack(pop). 我将#pragma pack(1)语句更改为#pragma pack(push,1)#pragma pack(pop)。 Its all working fine. 一切正常。 Hence my problem is solved; 因此,我的问题解决了; i learnt something. 我学到了一些东西。 Thanks a Lot. 非常感谢。 ! ! :-) :-)
Your program will never exit your while loop. 您的程序将永远不会退出while循环。
Solution. 解。
Add some kind of termination condition. 添加某种终止条件。
bool endIOThread = false;
while(!endIOThread)
{
std::cout << "\nChecking if Thread to be stopped: ";
{
boost::mutex::scoped_lock lock(muThreadControl);
endIOThread = cvThreadControl.wait_for(lock,
boost::chrono::seconds(1),
[this]{return threadToBeStopped;} ) == cv_status::no_timeout;
std::cout << endIOThread << std::endl
}
}
I copied your code and tried it on Linux. 我复制了您的代码,并在Linux上进行了尝试。
Your code as posted will not compile. 您发布的代码将无法编译。 I wonder if you tried it? 我想知道您是否尝试过?
The problem is that wait_for
with the predicate overload returns a bool
not a cv_status
. 问题是带有谓词重载的wait_for
返回的是bool
而不是cv_status
。 The inner loop times out, calls the predicate and returns. 内部循环超时,调用谓词并返回。
Your code works as expected if I remove the predicate lambda. 如果删除谓词lambda,您的代码将按预期工作。 It also works if I leave the lambda and remove the ==
comparison with the cv_status
. 如果我离开lambda并删除与cv_status
的==
比较,它cv_status
。
Perhaps if you do what I did and remove the using namespace boost;
也许,如果您做我所做的事情,并删除了using namespace boost;
line and then make all Boost objects explicit. 行,然后使所有Boost对象明确。
Here is my modified version which works for me: 这是适合我的修改后的版本:
#include <boost/chrono/chrono.hpp>
#include <boost/thread/thread.hpp>
#include <iostream>
class MyClassWithThread : public boost::enable_shared_from_this<MyClassWithThread>
{
boost::mutex muThreadControl;
boost::condition_variable cvThreadControl;
bool threadToBeStopped = false;
void ThreadFunction()
{
std::cout << "Beginning the Thread" << std::endl;
while(true)
{
bool endIOThread = false;
std::cout << "\nChecking if Thread to be stopped: ";
{
boost::mutex::scoped_lock lock(muThreadControl);
#if 1
endIOThread = cvThreadControl.wait_for(lock,
boost::chrono::seconds(1),
[this]{return threadToBeStopped;} );
#else
endIOThread = cvThreadControl.wait_for(lock,
boost::chrono::seconds(1)) == boost::cv_status::no_timeout;
std::cout << endIOThread << std::endl;
#endif
}
}
std::cout << "Exiting the Thread" << std::endl;
}
public:
boost::thread threadRunner;
MyClassWithThread()
{
threadRunner = boost::thread(&MyClassWithThread::ThreadFunction, this);
}
};
int main(int argc, char* argv[])
{
MyClassWithThread myclassWithThread;
myclassWithThread.threadRunner.join();
return 0;
}
Linux GCC build command: Linux GCC构建命令:
g++ -std=c++11 -pthread cond-wait-test.cpp -o cond-wait-test -lboost_system -lboost_thread -lboost_chrono
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.