C++ 条件变量通知未按预期工作

2024-04-27

我正在尝试在之前的工作完成后立即启动新线程worker_thread has started,但也许结束了,也可能没有结束。我已经用时间延迟替换了开始和结束的工作。我的代码是:

#include <iostream>
#include <string>
#include <mutex>
#include <condition_variable>
#include <future>
#include <atomic>
#include <chrono>
#include <thread>

std::mutex m;
std::condition_variable cv;
bool started = false;

void worker_thread()
{
    std::unique_lock<std::mutex> lk(m);

    static std::atomic<int> count(1);
    std::this_thread::sleep_for(std::chrono::milliseconds{(count % 5) * 100});
    std::cerr << "Start Worker thread: " << count << "\n";

    started = true;
    lk.unlock();
    cv.notify_one();

    std::this_thread::sleep_for(std::chrono::milliseconds{3000});
    std::cerr << "Exit Worker thread: " << count << "\n";
    ++count;
}

int main()
{
    while(1) {
        std::async(std::launch::async, worker_thread);
        std::unique_lock<std::mutex> lk(m);
        cv.wait(lk, []{return started;});
        started = false;
    }
}

输出看起来像这样:

Start Worker thread: 1
Exit Worker thread: 1
Start Worker thread: 2
Exit Worker thread: 2
Start Worker thread: 3
Exit Worker thread: 3
Start Worker thread: 4
Exit Worker thread: 4
Start Worker thread: 5
Exit Worker thread: 5

这不是我想要的行为。我想要的是(不完全是)这样的东西:

Start Worker thread: 1
Start Worker thread: 2
Start Worker thread: 3
Start Worker thread: 4
Exit Worker thread: 1
Exit Worker thread: 3
Exit Worker thread: 4
Exit Worker thread: 2
Start Worker thread: 5
Exit Worker thread: 5

目前,仅当上一个线程中的工作完成时才会启动下一个线程。但我想在上一个线程中开始工作后立即启动下一个线程,而不是等待它结束,只等待开始。


std::async返回一个std::future保存函数执行的结果。就您而言,它是一个临时对象,会立即被销毁。的文档std::future says:

这些操作不会阻止共享状态变为就绪状态,但如果满足以下所有条件则可能会阻止 http://en.cppreference.com/w/cpp/thread/future/%7Efuture:

✔ 共享状态是通过调用 std::async 创建的

✔ 共享状态尚未就绪

✔ 这是最后一次引用共享状态

所有这些都是真的,所以破坏它future将阻塞直到工作函数完成执行。

您可以创建分离线程来避免此问题:

std::thread(worker_thread).detach();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 条件变量通知未按预期工作 的相关文章

随机推荐

  • ASP.NET (MVC) 路线国际化

    我正在寻找一种在 ASP NET MVC 网站上国际化 本地化路由的解决方案 我偶然发现了这篇博客文章翻译路由 ASP NET MVC 和 Webforms http blog maartenballiauw be post 2010 01
  • 在 Selenium 中,ChromeDriver 可执行文件如何找到 Chrome 浏览器?

    对于Selenium 我们在System setProperty中定义chrome可执行路径 当在 driver get 中传递 URL 且 Chrome 调用时 1 chrome 可执行文件如何知道 Chrome 浏览器的实际安装位 置
  • 使用 mkl_malloc 进行内存对齐

    这个问题可能只是表明我还没有理解 C 中的一些重要内容 Intel Math Kernel 库提供了一种在分配内存时设置内存对齐的方法 另一方面 我只是通过引用将数组传递给 mkl lapack 例程 那么 lapack 例程如何知道数组的
  • 根据另一列修改 data.table 的列并添加新列

    我有一个data table DT有两列 V1 V2 1 1 3 2 2 4 3 3 5 4 2 2 5 3 8 6 1 4 7 2 5 对于每一行 我想采用相同的所有条目V1并添加V2条目然后划分V2按该总和输入并添加到第三列中 例如 在
  • lua http套接字超时

    LuaSocket HTTP 模块文档说可以在 HTTP 连接上设置超时 可以设置以下常量来控制 HTTP 模块的默认行为 PORT 用于连接的默认端口 PROXY 用于连接的默认代理 TIMEOUT 设置所有I O操作的超时时间 USER
  • Git:用一个命令推送到两个存储库

    我想要做git push origin and git push my other remote在同一条线上 可能的 您可以通过为您的应用添加额外的推送 URL 来获得相同的效果origin偏僻的 例如 如果现有遥控器的 URL 如下 gi
  • PyQt5:如何将 QPushButton 连接到插槽?

    好吧 几乎所有教程 可理解的用人类语言编写的文档都是针对 PyQt4 的 但是 PyQt5 改变了整个 将按钮连接到插槽 的工作方式 但我仍然不知道如何做到这一点 我在 QtDesigner 中做了一个快速 gui 并且有一个 QPushB
  • PhantomJS page.open 冻结

    我正在尝试使用 Capture 示例使用 PhantomJS 打开网站 var page require webpage create page open http github com function page render githu
  • 在后台播放音乐:AVAudioSessionInterruptionNotification 未触发

    我的应用程序正在播放背景很好 Pause and play即使我的应用程序是后台使用注册的方法也运行良好AVAudioSessionInterruptionNotification 问题到达场景的步骤 启动我的应用程序 gt 我的应用程序中
  • 生成易于记忆的随机标识符

    与所有开发人员一样 我们在日常工作中不断处理某种标识符 大多数时候 它与错误或支持票有关 我们的软件在检测到错误后 会创建一个包 该包的名称由时间戳和版本号格式化 这是创建合理唯一标识符以避免混淆包的一种廉价方法 例子 错误报告 20101
  • 为什么无法在 android 中包含 iostream?

    已安装 android ndk r7 并尝试编译 cpp 文件 include
  • 如何从 API 获取雅虎天气背景?

    我有一个天气小部件 我需要动态背景 雅虎有天气 API 但我无法找到与天气类型相关的背景图像 https weather yahoo com https weather yahoo com 这可能吗 var url http query y
  • 如何使用计划库运行异步函数?

    我正在使用discord py rewrite 编写一个discord 机器人 并且我想每天在特定时间运行一个函数 我对异步函数完全没有经验 而且我无法弄清楚如何在不使用 await 的情况下运行异步函数 这只是我的一段代码 这就是为什么有
  • 线程忙等待

    基本上 我需要忙着等待一些 html 出现在网页上 我创建了以下代码来忙等我 public void ExecuteBusyWaitThreads foreach Canidate canidate in allCanidates Thre
  • (Flutter) HTTPClient 参数无效:URI 中未指定主机

    目前正在开发一个小应用程序 允许用户查看存储在 Heroku 上的数据库 但是在使用数据库的 URL herokuapp com api 时 我遇到了上述问题 var client createHttpClient var response
  • Grails:如何更改默认视图位置?

    我有控制器AdminTagController 默认情况下视图将位于 adminTag文件夹 是否可以将此控制器的默认文件夹更改为 admin view 我可以为每个方法指定视图 但这并不酷 谢谢 可以用以下命令更改它拦截器后 http g
  • RSS:刷新率?

    我正在编写一个供自己使用的小应用程序 它将使用公开发布的 RSS 提要 据我所知 该协议中没有订阅 发布机制 我需要让我的应用程序定期通过 HTTP GET 获取 RSS 提要 如果是这样的话 我想每隔十分钟左右就抢一次 但我担心被视为施虐
  • 使用 Process.Start() 启动后等待 WPF 应用程序加载

    我有一个 WinForms 应用程序 它启动一个运行的 wpf 进程Process Start 我想知道 WPF 进程何时完成加载并且我可以访问process MainWindowHandle属性 在完全加载之前其值为 0 我尝试轮询 但句
  • 如何为列表中的项目添加背景颜色

    我有一个有序列表 ol li class odd Lorem ipsum dolor sit amet consectetur li li class even Some more text li ol 看起来像这样 Lorem ipsum
  • C++ 条件变量通知未按预期工作

    我正在尝试在之前的工作完成后立即启动新线程worker thread has started 但也许结束了 也可能没有结束 我已经用时间延迟替换了开始和结束的工作 我的代码是 include