Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用pthread_cancel取消线程:好做法还是坏做法 我在Linux上有一个C++程序(CCENTS 5.3),它生成多个线程,它们在无限循环中执行一个任务,并在某些分钟内休眠。 现在,我必须取消正在运行的线程,以防出现新的配置通知,并新启动一组线程,我使用了pthread_cancel。 我观察到的是,即使在接收到取消指示后,线程也没有停止,甚至在睡眠完成后,一些睡眠线程也出现了_C++_Linux_Pthreads - Fatal编程技术网

使用pthread_cancel取消线程:好做法还是坏做法 我在Linux上有一个C++程序(CCENTS 5.3),它生成多个线程,它们在无限循环中执行一个任务,并在某些分钟内休眠。 现在,我必须取消正在运行的线程,以防出现新的配置通知,并新启动一组线程,我使用了pthread_cancel。 我观察到的是,即使在接收到取消指示后,线程也没有停止,甚至在睡眠完成后,一些睡眠线程也出现了

使用pthread_cancel取消线程:好做法还是坏做法 我在Linux上有一个C++程序(CCENTS 5.3),它生成多个线程,它们在无限循环中执行一个任务,并在某些分钟内休眠。 现在,我必须取消正在运行的线程,以防出现新的配置通知,并新启动一组线程,我使用了pthread_cancel。 我观察到的是,即使在接收到取消指示后,线程也没有停止,甚至在睡眠完成后,一些睡眠线程也出现了,c++,linux,pthreads,C++,Linux,Pthreads,由于该行为不是所需的,在上述场景中使用pthread_cancel会引起关于是好的还是坏的实践的问题 请评论上述场景中pthread_cancel的用法。一般来说,线程取消并不是一个好主意。如果可能的话,最好有一个共享标志,线程使用它来中断循环。这样,您就可以让线程在实际退出之前执行它们可能需要执行的任何清理 在线程没有实际取消的问题上,POSIX规范确定了一组取消点()。只能在这些点取消线程。如果无限循环不包含取消点,可以通过调用pthread\u testcancel添加一个取消点。如果调用

由于该行为不是所需的,在上述场景中使用pthread_cancel会引起关于是好的还是坏的实践的问题


请评论上述场景中pthread_cancel的用法。

一般来说,线程取消并不是一个好主意。如果可能的话,最好有一个共享标志,线程使用它来中断循环。这样,您就可以让线程在实际退出之前执行它们可能需要执行的任何清理


在线程没有实际取消的问题上,POSIX规范确定了一组取消点()。只能在这些点取消线程。如果无限循环不包含取消点,可以通过调用
pthread\u testcancel
添加一个取消点。如果调用了代码> pthRead取消/<代码>,那么它将在此时生效。

如果您编写的异常安全C++代码(参见)比您的代码自然准备好了线程取消。这样您的析构函数就可以进行适当的清理。

我会使用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就是一个很好的工具。

你可以做下面的代码

#include <pthread.h>
#include <cxxabi.h>
#include <unistd.h>
...
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 );
}
#包括
#包括
#包括
...
无效*控制(无效*pparam)
{
尝试
{
//在这里做你的工作,也许是长循环
}   
捕获(abi::\u强制\u释放&)
{//handle pthread\u取消堆栈展开异常
投掷;
}
捕获(例外和例外)
{
掷骰子;
}
}
int main()
{
pthread_t tid;
int rtn;
rtn=pthread_create(&tid,NULL,Control,NULL);
美国LEEP(500);
//这里还有其他工作吗
rtn=pthtead\U cancel(tid);
}

+1为了避免取消,这是最快的内存泄漏方法,甚至更糟。礼貌地问:)似乎我必须使用共享标志更改线程终止的逻辑。但另一方面,我的程序将取消状态的线程设置为异步,我相信这与调用相应的清理处理程序后立即终止线程有关。@user584631:pthreads手册页上说,当模式设置为异步时,可以立即取消,但是系统不需要这样做。系统不需要立即取消线程,直到线程执行仍然不知道取消,是吗?不同意
pthread\u cancel()
可能更易于使用。如果调用
pthread\u cleanup\u push()
pthread\u cleanup\u pop()
来设置清理处理程序,则可以避免资源泄漏。如果OP知道它们永远不需要在另一个pthreads实现上运行,这没关系,但我建议不要依赖通过异常实现的线程取消。使用标志将线程退出“隐藏内容”的领域,并进入您可以看到的代码中,使以后的维护人员更容易操作。我对这个问题已经有多年的经验,我认为最好的办法是避免取消,因为当你在组合中有取消时,总会有一些事情让你绊倒。这篇博客文章描述了为什么RAII不能与取消组合:@erenon很好的文章,但这只是故事的一半。“可以在析构函数中禁用线程取消功能。”MaximEgorushkin对一个5年前的问题发表了很晚的评论,但我喜欢你的想法。我可以用GCC指定所有的C++ DeStruts应该自动地(暂时)禁用pthRead取消吗?@ EikalAP。