Poco::Thread 多次启动挂断并快速连续加入

Poco::Thread hangup on multiple start and join in quick succession

我在使用 Poco::Thread 时遇到了问题。此代码在大约 4K 次迭代时挂起。使用 GCC 4.6.1 为 QNX5 构建,POCO_VERSION 0x01040602。

#include "Poco/Thread.h"
using namespace Poco;

class SignalAdapter: public Runnable
{
public:
    SignalAdapter()
    {}

    virtual void run()
    {
        //printf( "This is thread %d\n", Thread::currentTid() );
    }
};

int main() {
  Thread oThread;
  SignalAdapter oSignalAdapter{};

  for (auto i = 0; i < 1e5; ++i)
  {
      oThread.start(oSignalAdapter);
      if (oThread.isRunning())
          oThread.join();

  }
}

但是,直接使用 PThread 可以正常工作,在 Windows 上也可以正常工作。我很乐意提供一些帮助。

Poco::Thread 的内部状态不是线程安全的(原子的)。您将在 start()join()isRunning() 中出现竞争条件,导致线程泄漏(不加入当前的 Runnable)。

将 g++ 与 -fsanitize=thread -static-libtsan 结合使用:

WARNING: ThreadSanitizer: thread leak (pid=24366)
  Thread T1 (tid=32349, finished) created by main thread at:
    #0 pthread_create <null> (Test+0x0000004945e7)
    #1 Poco::ThreadImpl::startImpl(Poco::Runnable&) <null> (libPocoFoundation.so.20+0x0000000f8d67)
    #2 __libc_start_main <null> (libc.so.6+0x00000002082f)

  And 11 more similar thread leaks.

查看 POCO 的来源,Poco::Event(由 Poco::Thread` 内部使用)似乎是实施中有问题的部分。

我建议不要使用 Poco::Thread 而是使用 std::thread (C++11)。