2009-11-03 86 views
30

我认为可以加入会表明这一点,但是,似乎并不是这样。如何可靠地告诉boost线程是否已退出运行方法?

在工人类,我试图表明,它仍然在通过谓语处理:

bool isRunning(){return thread_->joinable();} 

那不是已经退出不会是可连接线程?我错过了什么...... boost thread :: joinable的含义是什么?

回答

30

既然你可以加入一个线程,即使它已经终止,joinable()仍然会返回true,直到你调用join()或detach()。如果您想知道线程是否仍在运行,您应该能够以等待时间0调用timed_join。请注意,这可能会导致竞争条件,因为线程可能会在呼叫之后立即终止。

+6

说它可能导致竞争条件有点误导。 'timed_join'本身不能做到这一点。如果根据调用的结果做出任何不正确的假设,当然可能最终会出现竞争条件,但这与'timed_join'的关系不如您假设该调用的结果仍然有效。无论如何,+1 – jalf 2009-11-03 14:05:42

+35

我认为这真的很糟糕。为什么助推器设计师从来不会想到直觉或初学者。一个简单的isRunning()方法就足够了。相反,他们强迫一个人在这种情况下直接使用一个不应该使用的函数。我不想尝试加入这个线程,我只想快速测试它是否仍然有效。这是废话。浪费了很多时间才找到这个。在“文档”中也不是一个该死的词。 – AndreasT 2010-01-11 14:26:56

+0

线程可以处于3种状态:运行,分离,不运行。 – 2012-12-04 12:28:17

3

你从根本上做不到这一点。原因是,两个可能的答案是“是”和“不是当我上次看,但也许现在”。没有可靠的方法可以确定线程仍在其运行方法中,即使有可靠的方法来确定相反的方法。

+7

您从根本上可以做到这一点。您可以在任何给定时间可靠地查询或“观察”线程的状态。问题在于,根据您返回的状态,您无法对交互作出任何假设,也就是说,当您获得信息“线程仍在运行”时,它可能已经在获取该信息所用的时间内停止,但这并不重要。对不起,但这篇文章没有任何帮助。 – AndreasT 2010-01-11 14:36:24

+0

@AndreasT:如果你不能做任何假设,这可能有用吗? – 2013-10-08 17:01:36

5

使用thread::timed_join()以最小超时。如果线程仍在运行,它将返回false。

+0

这是错误的。如果一个线程被分离,它将返回false。事实上,您需要反过来读取它:如果返回true,线程正在运行,然后在超时期间停止 – 2012-12-04 12:26:36

+0

@GaetanoMendola:不完全是,当您调用timed_join并且结果为true时,该线程可能会停止并可加入。 – 2013-10-08 17:03:58

0

这是一个有点粗糙,但作为现在它仍然符合我的要求。 :)我使用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(); 
} 
0

如果运行线程的函数足够简单,最简单的方法是在函数完成时将变量设置为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); 
    } 
}; 
0

这可能不是直接回答你的问题,但我看到了线程的概念作为一个真正的轻量机制,并没有刻意的,除了同步机制事情。我认为放置“正在运行”的正确位置是在定义线程函数的类中。请注意,从设计的角度来看,您可以在中断时退出线程,但仍未完成工作。如果要在线程完成后清理线程,可以将其包装在安全的指针中,并将其交给工人类。

+0

我相信这会更好,如果您可以使用代码示例进行说明,并将段落分段以便于阅读。 – phaberest 2016-02-11 19:20:55

相关问题