翻译:Cancelling a thread using pthread_cancel : good practice or bad

Stack overflow地址:c++ - Cancelling a thread using pthread_cancel : good practice or bad - Stack Overflow


翻译:

我有一个C++程序在Linux(CentOS 5.3),它产生多个线程,线程在无限循环执行一个任务并睡眠一定的时间。一旦一个新的配置提醒到来,我就需要取消正在运行的线程然后开启一些新的线程去更新它们,为此我使用了pthread_cancel。我观察到,线程不会停止即使收到了取消指示命令,甚至一些睡眠的线程在睡眠之后又出现了。

这并不是希望的行为,请评论一下在上面的场景中 pthread_cancel的用法。



Answers1:

通常情况下线程取消并不是一个好主意。如果有可能的话,共享一个标识,它用于线程退出它们的循环。那样,你需要让线程执行一些资源回收操作在真正的退出之前。

在这个问题上,线程实际上没有取消,POSIX指出了一组取消情况(man 7 pthreads)。只有在这些情况下线程才可以取消。如果你得无限循环没有包含一个取消情况,那么你可以添加一个通过调用 pthread_testcancel。如果 pthread_cancel 被调用了,它将会在这里执行。


Answers2:

如果你在写异常安全的C++代码(查阅https://www.boost.org/community/exception_safety.html),那么你得代码就有线程取消的功能。https://udrepper.livejournal.com/21541.html因此你得析构函数可以做正确的资源释放。


Answers3:

我使用 boost::asio。

就像下面这样:

struct Wait {

  Wait() : timer_(io_service_), run_(true) {}

  boost::asio::io_service io_service_;

  mutable boost::asio::deadline_timer timer_;

  bool run_;

};

void Wait::doWwork() {

  while (run) {

    boost::system::error_code ec;

    timer_.wait(ec);

    io_service_.run();

    if (ec) {

      if (ec == boost::asio::error::operation_aborted) {

        // cleanup

      } else {

        // Something else, possibly nasty, happened

      }

    }

  }

}

void Wait::halt() {

  run_ = false;

  timer_.cancel();

}

一旦你掌握了它,asio是一个完美的工具。


Answers4:

你可以使用想下面这样的代码:

#include

#include

#include

...

void *Control(void* pparam)

{

    try

    {

        // do your work here, maybe long loop

    } 

    catch (abi::__forced_unwind&)

    {  // handle pthread_cancel stack unwinding exception

        throw;

    }

    catch (exception &ex)

    {

        throw ex;

    }

}

int main()

{

    pthread_t tid;

    int rtn;

    rtn = pthread_create( &tid, NULL, Control, NULL );

    usleep(500);

    // some other work here

    rtn = pthtead_cancel( tid );

}

你可能感兴趣的:(翻译:Cancelling a thread using pthread_cancel : good practice or bad)