【问题标题】:How to break from while loop with active thread如何使用活动线程从while循环中中断
【发布时间】:2017-06-16 03:52:24
【问题描述】:

我知道这不是表达我的问题的最佳方式。在我的服务器中,一些问题基本上归结为 - 一旦满足条件A,你如何打破while循环?如果满足条件B,是否可以销毁特定线程?

不幸的是,除非我能从循环中中断,否则主线程被 recvfrom() 函数永远阻塞了。

while (1)
{
  recBytes = recvfrom(sock, packetBuff, 8, 0, (struct sockaddr *) &client, &SockLength);

  std::thread TX([&] 
  {
    //process packet task

    if(conditionA == 1)
      break from while loop

    if(conditionB == 1)
      destroy any active threads spawned by TX

    .
    .
    .
    much more tasks

  });

  TX.detach();
} 

.
.
.
continue rest of code

提前致谢!

【问题讨论】:

  • 你考虑过使用一些 asio 库吗?我想到了 boost.asio,但也有其他可用的库。即使在上述情况下,从另一个线程关闭套接字也很简单有效,足以从 recv_from 退出,并检查错误情况,我希望你已经这样做了。 break 语句将退出循环。
  • 我可以推荐这个关于 YT 的讲座:“时间的历史:异步 C++ - Steven Simpson”吗?在使用现代 c++ 技术设计客户端/服务器应用程序之前,值得花时间。无论您的应用需要多大的尺寸。
  • @MichaëlRoy 你介意用代码告诉我这是什么样子吗?
  • 检查 boost.asio 代码示例:boost.org/doc/libs/1_64_0/doc/html/boost_asio/example/cpp11/…。请注意,服务器可以在单个线程上运行时处理许多客户端。上述演示文稿中的代码:github.com/stevejims/acpp。其中一些代码在单线程上运行时可以同时处理 50+k 个请求,这总是很有趣。
  • 为什么要退出循环?这将有效地杀死你的守护进程。

标签: multithreading c++11 lambda break


【解决方案1】:

中断阻塞 I/O 调用的标准方法是用 select()/poll()/etc 替换它,等待 2 个套接字:您的数据套接字和非阻塞通知管道。如果 select() 报告您可以读取或写入数据套接字,那么您就可以以非阻塞方式执行此操作。如果它报告通知管道上有可用的数据,则您会中断循环。任何线程都可以将单个字节写入非阻塞通知管道,以导致另一个线程中的 select() 返回。

至于销毁其他线程,如果没有这些线程的合作,您就无法做到这一点。基本上,您需要一种方法来通知他们需要退出。如果这些线程不进行阻塞调用,那么一个带有定期检查的简单原子标志就可以了。否则,您需要一种方法来中断阻塞调用。如果是 I/O 调用,则引入另一个通知管道。如果它在条件变量上阻塞,请使用 std::condition_variable::notify_all()。

【讨论】:

猜你喜欢
  • 2014-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-06
  • 1970-01-01
  • 2014-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多