如何可靠地判断boost线程是否已退出其run方法?

时间:2021-09-07 21:08:05

I assumed joinable would indicate this, however, it does not seem to be the case.

我认为可加入会表明这一点,但是,似乎并非如此。

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是什么意思?

7 个解决方案

#1


30  

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.

由于即使在线程终止后你也可以加入一个线程,所以在你调用join()或detach()之前,joinable()仍会返回true。如果你想知道一个线程是否仍在运行,你应该能够在等待时间为0的情况下调用timed_join。注意这可能导致竞争条件,因为线程可能在调用之后立即终止。

#2


5  

Use thread::timed_join() with a minimal timeout. It will return false if the thread is still running.

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

#3


3  

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方法中,即使有可靠的方法来确定相反的方法。

#4


3  

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

#5


0  

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();
}

#6


0  

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);
    }
};

#7


0  

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.

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

#1


30  

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.

由于即使在线程终止后你也可以加入一个线程,所以在你调用join()或detach()之前,joinable()仍会返回true。如果你想知道一个线程是否仍在运行,你应该能够在等待时间为0的情况下调用timed_join。注意这可能导致竞争条件,因为线程可能在调用之后立即终止。

#2


5  

Use thread::timed_join() with a minimal timeout. It will return false if the thread is still running.

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

#3


3  

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方法中,即使有可靠的方法来确定相反的方法。

#4


3  

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

#5


0  

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();
}

#6


0  

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);
    }
};

#7


0  

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.

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