【发布时间】:2010-12-12 15:37:30
【问题描述】:
我认为 joinable 会表明这一点,但似乎并非如此。
在工人阶级中,我试图表明它仍在通过谓词进行处理:
bool isRunning(){return thread_->joinable();}
不是已经退出的线程不能加入吗?我错过了什么...... boost thread::joinable 的含义是什么?
【问题讨论】:
标签: c++ boost multithreading
我认为 joinable 会表明这一点,但似乎并非如此。
在工人阶级中,我试图表明它仍在通过谓词进行处理:
bool isRunning(){return thread_->joinable();}
不是已经退出的线程不能加入吗?我错过了什么...... boost thread::joinable 的含义是什么?
【问题讨论】:
标签: c++ boost multithreading
因为即使在线程终止后你也可以加入线程,所以 joinable() 仍然会返回 true,直到你调用 join() 或 detach()。如果您想知道某个线程是否仍在运行,您应该能够在等待时间为 0 的情况下调用 timed_join。请注意,这可能会导致竞争条件,因为线程可能会在调用后立即终止。
【讨论】:
timed_join 单独无法做到这一点。如果您根据调用的结果做出任何不正确的假设,那么您当然可能会遇到竞争条件,但这与 timed_join 的关系不如您假设该调用的结果仍然有效。无论如何,+1
使用thread::timed_join() 并尽量缩短超时时间。如果线程仍在运行,它将返回 false。
示例代码:
thread_->timed_join(boost::posix_time::seconds(0));
【讨论】:
我正在使用 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
【讨论】:
你根本无法做到这一点。原因是两个可能的答案是“是”和“不是我上次看的时候,但也许是现在”。没有可靠的方法来确定线程是否仍在其 run 方法中,即使有可靠的方法来确定相反的情况。
【讨论】:
这有点粗糙,但到目前为止它仍然可以满足我的要求。 :) 我正在使用 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();
}
【讨论】:
如果运行线程的函数足够简单,最简单的方法是在函数完成时将变量设置为 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);
}
};
【讨论】:
这可能不是您问题的直接答案,但我认为线程概念是一种非常轻量级的机制,并且除了同步机制之外,故意没有任何东西。我认为放置“正在运行”的正确位置是在定义线程函数的类中。请注意,从设计的角度来看,您可以在中断时退出线程,但您的工作仍然没有完成。如果你想在线程完成后清理它,你可以将它包装在一个安全的指针中,然后交给worker类。
【讨论】: