【问题标题】:How can I tell reliably if a boost thread has exited its run method?如何可靠地判断 boost 线程是否已退出其运行方法?
【发布时间】:2010-12-12 15:37:30
【问题描述】:

我认为 joinable 会表明这一点,但似乎并非如此。

在工人阶级中,我试图表明它仍在通过谓词进行处理:

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

不是已经退出的线程不能加入吗?我错过了什么...... boost thread::joinable 的含义是什么?

【问题讨论】:

    标签: c++ boost multithreading


    【解决方案1】:

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

    【讨论】:

    • 说它可能导致竞争条件有点误导。 timed_join 单独无法做到这一点。如果您根据调用的结果做出任何不正确的假设,那么您当然可能会遇到竞争条件,但这与 timed_join 的关系不如您假设该调用的结果仍然有效。无论如何,+1
    • 我认为这真的很糟糕。为什么 boost 设计师从不考虑直觉或初学者。一个简单的 isRunning() 方法就足够了。相反,他们强迫人们使用在这种情况下直觉上不应该使用的功能。我不想尝试加入线程,我只想快速测试它是否仍然有效。这是废话。在我发现这个之前浪费了很多时间。 “文档”中也没有一个该死的词。
    • @AndreasT:Boost 是由像你这样的人完成的。如果你有一个具体的建议,那就去做吧。如果您另外提供带有文档和测试的补丁,那就更好了。
    • 这个答案对于 windows 上的 boost 1.55 无效:timed_joined() 已被弃用,调用 try_join_for(0) 返回 false 而不检查线程是否已完成。已为以下版本的 boost 发布了补丁,但从 boost 的开发人员的角度来看,尚不清楚预期的行为是什么:svn.boost.org/trac/boost/ticket/9618
    【解决方案2】:

    使用thread::timed_join() 并尽量缩短超时时间。如果线程仍在运行,它将返回 false。

    示例代码:

    thread_->timed_join(boost::posix_time::seconds(0));
    

    【讨论】:

    • 这是错误的。如果线程被分离,它将返回 false。实际上,您需要以另一种方式阅读它:如果返回 true,则线程正在运行,然后在超时期间停止
    • @GaetanoMendola:不完全是,当您调用 timed_join 并且结果为 true 时,线程可能会停止并加入。
    • 注意:timed_join() 在 boost 3.0 之后被弃用。使用 try_join_for 或 try_join_until。
    【解决方案3】:

    我正在使用 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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 你基本上可以做到这一点。您可以在任何给定时间可靠地查询或“观察”线程的状态。问题在于您无法根据返回的状态对交互做出任何假设,这意味着当您获得“线程仍在运行”信息时,它可能已经在获取该信息所需的时间内停止,但这很少是关键的。抱歉,这篇文章没有任何帮助。
      • @AndreasT:如果你不能做任何假设,这有什么用?
      【解决方案5】:

      这有点粗糙,但到目前为止它仍然可以满足我的要求。 :) 我正在使用 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】:

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

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

          【讨论】:

          • 我相信如果你用代码示例澄清一下并将你的文本分成段落以促进可读性会更好。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多