[英]condition_variable::wait_for method not returning - even after the timeout
我來自C#編碼經驗; 我開始學習C ++,並利用Boost庫進行線程化。 我編寫了以下類-嘗試將成員函數作為線程執行。 編寫以下簡單代碼,我希望線程函數內的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;
}
要在Linux上構建:
g++ -std=c++11 -pthread cond-wait-test.cpp -o cond-wait-test -lboost_system -lboost_thread -lboost_chrono
但是,當我執行代碼時,我注意到的是線程的執行在調用wait_for方法時被阻塞了。 永遠。 盡管有超時時間。 此外,系統的資源監視器顯示處理器核心已被100%利用。
誰能解釋一下代碼中發生了什么?
正如@Zan Lynx所建議的,罪魁禍首是#pragma pack語句。 最初,我僅使用#pragma pack(1)對某些結構進行字節對齊。 這將許多互斥鎖結構影響到1字節對齊。
我將#pragma pack(1)語句更改為#pragma pack(push,1)#pragma pack(pop)。 一切正常。 因此,我的問題解決了; 我學到了一些東西。 非常感謝。 ! :-)
您的程序將永遠不會退出while循環。
解。
添加某種終止條件。
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
}
}
我復制了您的代碼,並在Linux上進行了嘗試。
您發布的代碼將無法編譯。 我想知道您是否嘗試過?
問題是帶有謂詞重載的wait_for
返回的是bool
而不是cv_status
。 內部循環超時,調用謂詞並返回。
如果刪除謂詞lambda,您的代碼將按預期工作。 如果我離開lambda並刪除與cv_status
的==
比較,它cv_status
。
也許,如果您做我所做的事情,並刪除了using namespace boost;
行,然后使所有Boost對象明確。
這是適合我的修改后的版本:
#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構建命令:
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.