【问题标题】:std::future.wait_for blocking foreverstd::future.wait_for 永远阻塞
【发布时间】:2019-12-08 23:48:26
【问题描述】:

我正在创建 SSL 套接字,当我尝试连接到该套接字时,我的程序挂起。

我发现服务器不发送任何数据的问题,因此 SSL 连接正在等待任何响应。

我决定创建未来并在超时后将其杀死。但它仍然挂着。

如果你看到代码,下面的部分没有被执行:cout<<"TEST";

{

     std::future<void> future = std::async(std::launch::async, 
     [&](){ 
              err = SSL_connect (m_ssl); 
          });

     std::future_status status;
     status = future.wait_for(std::chrono::seconds(t_timeout));
}

cout<<"TEST";

为了模拟我刚刚运行的服务器的停止响应:

for item in $(seq 1 1000); do sudo nc -i 100000ms -l 443 >> log.out; done;

如何终止 SSL 连接? 我想在杀死未来之后继续执行代码。

编辑: 我不想为此提出另一个问题。 答案:所以我现在确定这是因为未来的析构函数。它正在等待来自未来主体的代码完成。

问题 2: 我该如何解决上述问题?我想在未来所在的范围之后执行代码。

是否可以创建线程并等待直到超时或 ssl 某些互斥锁被解锁?

【问题讨论】:

  • 你真的检查过t_timeout的值吗?
  • 是的,当我使用 gdb 进行调试时,它的 3 秒和未来正在退出,它退出范围并在 cout&lt;&lt;"TEST"; 之前停止执行(挂起)
  • 如果SSL_connect 无限期阻塞并且不返回,那么线程或异步代码都无助于绕过它。没有所谓的“杀死”未来。
  • @VTT 有什么可以帮助我的吗?手动创建和杀死线程?
  • “永远阻塞”功能被设计破坏,没有办法绕过它。最多你会留下泄漏的阻塞线程。切换到一些适当的库/API 可能会有所帮助。

标签: c++ multithreading sockets ssl future


【解决方案1】:

您的代码的问题是,当未来超出范围时,其析构函数可能会阻塞,如 documentation 中报告的 std::future&lt;T&gt;::~future:

它明确地说:

... 不会阻塞共享状态准备就绪,除非满足以下所有条件时它可能会阻塞:共享状态是通过调用 std::async 创建的,共享状态尚未创建准备好了,这是对共享状态的最后一次引用。

在你的情况下:

  1. 共享状态尚未准备好:SSL 永远挂起
  2. 这是对共享状态的唯一(也是最后一个)引用。

您的问题的解决方案是您必须使变量std::future&lt;void&gt; future 的范围超过您不想被阻塞的代码部分。

检查这些答案:

LIVE DEMO

【讨论】:

  • 因此,如果他想查看cout&lt;&lt;"TEST",他不应该将未来包含在一个块中,因为在块的末尾调用了它的析构函数。
  • 如果代码在函数内部,他想在 int main() 中打印 test 怎么办?
  • @Rostin 那是另一个问题 =)
  • 我更新了问题并发布了另一个问题。谢谢 我们可以在这里继续讨论吗?
  • @DavideSpataro。太好了 :D 非常感谢你,我会将它作为一个类属性来解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-24
  • 1970-01-01
相关资源
最近更新 更多