C++ 如何可靠地判断 boost 线程是否已退出其 run 方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1667420/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I tell reliably if a boost thread has exited its run method?
提问by JeffV
I assumed joinable would indicate this, however, it does not seem to be the case.
我认为 joinable 会表明这一点,但是,情况似乎并非如此。
In a worker class, I was trying to indicate that it was still processing through a predicate:
在工人类中,我试图表明它仍在通过谓词进行处理:
bool isRunning(){return thread_->joinable();}
Wouldn't a thread that has exited not be joinable? What am I missing... what is the meaning of boost thread::joinable?
退出的线程不是不可连接的吗?我错过了什么...... boost thread::joinable 是什么意思?
采纳答案by interjay
Since you can join a thread even after it has terminated, joinable() will still return true until you call join() or detach(). If you want to know if a thread is still running, you should be able to call timed_join with a wait time of 0. Note that this can result in a race condition since the thread may terminate right after the call.
由于您可以在线程终止后加入它,所以 joinable() 仍然会返回 true,直到您调用 join() 或 detach()。如果您想知道线程是否仍在运行,您应该能够以 0 的等待时间调用 timed_join。请注意,这可能导致竞争条件,因为线程可能会在调用后立即终止。
回答by Joakim Karlsson
Use thread::timed_join()with a minimal timeout. It will return false if the thread is still running.
使用具有最小超时的thread::timed_join()。如果线程仍在运行,它将返回 false。
Sample code:
示例代码:
thread_->timed_join(boost::posix_time::seconds(0));
回答by pocruadhlaoich
I am using boost 1.54, by which stage timed_join() is being deprecated. Depending upon your usage, you could use joinable() which works perfectly for my purposes, or alternatively you could use try_join_for() or try_join_until(), see:
我正在使用 boost 1.54,在哪个阶段 timed_join() 被弃用。根据您的使用情况,您可以使用 joinable(),它非常适合我的目的,或者您可以使用 try_join_for() 或 try_join_until(),请参阅:
http://www.boost.org/doc/libs/1_54_0/doc/html/thread/thread_management.html
http://www.boost.org/doc/libs/1_54_0/doc/html/thread/thread_management.html
回答by MSalters
You fundamentally can't do this. The reason is that the two possible answers are "Yes" and "Not when I last looked but perhaps now". There is no reliable way to determine that a thread is still inside its run method, even if there was a reliable way to determine the opposite.
你基本上不能这样做。原因是两个可能的答案是“是”和“不是我上次看的时候,但也许是现在”。没有可靠的方法来确定一个线程仍然在它的 run 方法中,即使有一个可靠的方法来确定相反的情况。
回答by Adonai
This is a bit crude but as of now it's still working for my requirements. :) I'm using boost 153 and qt. I created a vector of int for tracking the "status" of my threads. Every time I create a new thread, I add one entry to thread_ids with a value of 0. For each thread created, I pass an ID so I know what part of thread_ids I'm supposed to update. Set the status to 1 for running and other values depending on what activity I am currently doing so I know what activity was being done when the thread ended. 100 is the value I set for a properly finished thread. I'm not sure if this will help but if you have other suggestions on how to improve on this let me know. :)
这有点粗糙,但到目前为止它仍然可以满足我的要求。:) 我正在使用 boost 153 和 qt。我创建了一个 int 向量来跟踪线程的“状态”。每次创建新线程时,我都会向 thread_ids 添加一个值为 0 的条目。对于创建的每个线程,我都会传递一个 ID,以便我知道应该更新 thread_ids 的哪一部分。根据我当前正在执行的活动将状态设置为 1 以进行运行和其他值,以便我知道线程结束时正在执行的活动。100 是我为正确完成的线程设置的值。我不确定这是否会有所帮助,但如果您有其他关于如何改进的建议,请告诉我。:)
std::vector<int> thread_ids;
const int max_threads = 4;
void Thread01(int n, int n2)
{
thread_ids.at(n) = 1;
boost::this_thread::sleep(boost::posix_time::milliseconds(n2 * 1000));
thread_ids.at(n) = 100;
qDebug()<<"Done "<<n;
}
void getThreadsStatus()
{
qDebug()<<"status:";
for(int i = 0; i < max_threads, i < thread_ids.size(); i++)
{
qDebug()<<thread_ids.at(i);
}
}
int main(int argc, char *argv[])
{
for(int i = 0; i < max_threads; i++)
{
thread_ids.push_back(0);
threadpool.create_thread(
boost::bind(&boost::asio::io_service::run, &ioService));
ioService.post(boost::bind(Thread01, i, i + 2));
getThreadsStatus();
}
ioService.stop();
threadpool.join_all();
getThreadsStatus();
}
回答by Blackzafiro
The easiest way, if the function that is running your thread is simple enough, is to set a variable to true when the function is finished. Of course, you will need a variable per thread, if you have many a map of thread ids and status can be a better option. I know it is hand made, but it works fine in the meanwhile.
如果运行线程的函数足够简单,最简单的方法是在函数完成时将变量设置为 true。当然,每个线程都需要一个变量,如果你有很多线程 id 和状态的映射可能是一个更好的选择。我知道它是手工制作的,但同时效果很好。
class ThreadCreator
{
private:
bool m_threadFinished;
void launchProducerThread(){
// do stuff here
m_threadRunning = true;
}
public:
ThreadCreator() : m_threadFinished(false) {
boost::thread(&Consumer::launchProducerThread, this);
}
};
回答by Brian Balke
This may not be a direct answer to your question, but I see the thread concept as a really light-weight mechanism, and intentionally devoid of anything except synchronization mechanisms. I think that the right place to put "is running" is in the class that defines the thread function. Note that from a design perspective, you can exit the thread on interrupt and still not have your work completed. If you want to clean up the thread after it's completed, you can wrap it in a safe pointer and hand it to the worker class.
这可能不是您问题的直接答案,但我认为线程概念是一种非常轻量级的机制,并且除了同步机制外,故意没有任何东西。我认为放置“正在运行”的正确位置是在定义线程函数的类中。请注意,从设计的角度来看,您可以在中断时退出线程并且仍然没有完成您的工作。如果你想在线程完成后清理它,你可以将它包装在一个安全的指针中,并把它交给工作类。