如何在屏障处正确同步线程

2024-04-25

我遇到一个问题,我很难判断应该使用哪个同步原语。

我正在创建 n 个在内存区域上工作的并行线程,每个线程都分配给该区域的特定部分,并且可以独立于其他线程完成其任务。在某些时候,我需要收集所有线程的工作结果,这是使用屏障的一个很好的例子,这就是我正在做的事情。

我必须使用 n 个工作线程之一来收集其所有工作的结果,为此,我在线程函数中的计算代码后面添加了以下代码:

if (pthread_barrier_wait(thread_args->barrier)) {
   // Only gets called on the last thread that goes through the barrier
   // This is where I want to collect the results of the worker threads
}

到目前为止一切顺利,但现在我陷入困境:上面的代码处于循环中,因为我希望线程在一定数量的循环旋转中再次完成工作。这个想法是,每次pthread_barrier_wait解除阻塞意味着所有线程都已完成其工作,循环/并行工作的下一次迭代可以重新开始。

这样做的问题是,在其他线程再次开始处理该区域之前,不能保证结果收集器块语句的执行,因此存在竞争条件。我正在考虑使用这样的 UNIX 条件变量:

// This code is placed in the thread entry point function, inside
// a loop that also contains the code doing the parallel
// processing code.

if (pthread_barrier_wait(thread_args->barrier)) {
    // We lock the mutex
    pthread_mutex_lock(thread_args->mutex);
    collectAllWork(); // We process the work from all threads
    // Set ready to 1
    thread_args->ready = 1;
    // We broadcast the condition variable and check it was successful
    if (pthread_cond_broadcast(thread_args->cond)) {
        printf("Error while broadcasting\n");
        exit(1);
    }
    // We unlock the mutex
    pthread_mutex_unlock(thread_args->mutex);
} else {
    // Wait until the other thread has finished its work so
    // we can start working again
    pthread_mutex_lock(thread_args->mutex);
    while (thread_args->ready == 0) {
        pthread_cond_wait(thread_args->cond, thread_args->mutex);
    }
    pthread_mutex_unlock(thread_args->mutex);
}

这有多个问题:

  • 因为某些原因pthread_cond_broadcast永远不会解锁任何其他正在等待的线程pthread_cond_wait, 我不知道为什么。
  • 如果一个线程会发生什么pthread_cond_waits after收集器线程已广播?我相信while (thread_args->ready == 0) and thread_args->ready = 1防止这种情况发生,但请看下一点......
  • 在下一个循环旋转中,ready仍将被设置为1因此没有线程会调用pthread_cond_wait再次。我没有看到任何可以正确设置的地方ready回到0:如果我在之后的 else 块中执行此操作pthread_cond_wait,有可能另一个没有 cond 等待的线程正在读取1并开始等待,即使我已经从if block.

请注意,我需要为此使用障碍。

我该如何解决这个问题?


您可以使用两个障碍(工作和收集器):

while (true) {

    //do work

    //every thread waits until the last thread has finished its work
    if (pthread_barrier_wait(thread_args->work_barrier)) {
        //only one gets through, then does the collecting
        collectAllWork();
    }

    //every thread will wait until the collector has reached this point
    pthread_barrier_wait(thread_args->collect_barrier);

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

如何在屏障处正确同步线程 的相关文章

随机推荐

  • 将表部署到表存储中的最佳方法

    你能让我知道吗 进行表存储部署的最佳方法是什么 因为我的开发团队询问他们有很多表 每个表都有数千个条目 因此 他们要求我咨询任何微软团队或博客人们检查进行表存储部署的最佳方法 您知道我们该怎么做吗 因为脚本每次都会耗尽和插入数千个条目 我们
  • Windows 7 上的 VirtualBox 端口转发不起作用

    Windows 7 上的 VirtualBox 端口转发不起作用 我尝试通过端口转发从我的 Windows 7 主机 ssh 到我的 VirtualBox 但 VirtualBox 不会打开端口进行侦听 我可以通过打开 VirtualBox
  • 如何在 Cocoa 中检查文件是否被锁定?

    有没有API可以检查文件是否被锁定 我在中找不到任何 APINSFileManagerclass 让我知道是否有任何API可以检查文件的锁定 我发现以下与文件锁定相关的链接 http lists apple com archives coc
  • 使用 MVC 和 DAO 模式在 JSP 页面中的 HTML 中显示 JDBC 结果集

    我正在使用 JSP 和 JDBC 实现 MVC 我已将数据库类文件导入到 JSP 文件中 并且想显示数据库表的数据 我不知道该如何归还ResultSet从 Java 类到 JSP 页面并将其嵌入到 HTML 中 我怎样才能实现这个目标 在设
  • 从命令行安装 Oracle 客户端,无需用户交互

    我正在寻找一种在 Windows 上安装 Oracle 客户端但从命令行运行的方法 为了自动运行它应有没有用户交互 对于 Oracle Universal Installer 的命令行选项 Oracle 文档非常稀疏 即使运行设置为setu
  • Golang 结构继承没有按预期工作?

    查看这个沙箱 https play golang org p elIHgHAZjT 声明从不同结构继承的结构时 type Base struct a string b string type Something struct Base c
  • 可以在没有 dynamoDB 的情况下使用 AWS App-Sync

    我对 Amazon app sync 的离线和同步功能感兴趣 但我想知道它是否可以在没有 dynamoDB 作为后端的情况下使用 用 VTL 为 dynamoDB 编写的 graphQL 解析器看起来很糟糕 看来使用 mongo 后端会好得
  • 是否可以在越狱的ios上使用外部键盘模拟触摸事件?

    是否可以在 iOS 越狱以及越狱涉及的所有元素上模拟特定屏幕坐标中的触摸事件 按下物理外部键盘 通过相机连接套件或蓝牙的 USB 上的特定按键 我会用它来用脚按下应用程序 振幅 中的按钮 我想使用键盘作为脚踏开关 仅供私人使用 没有应用商店
  • 如何使用 OData 在单个 POST 请求中正确创建和链接一对一关系

    在 OData Operations 文档的第 2 4 节第四段中 它写道 在使用 POST 创建实体时 也可以在同一请求中创建链接 但是 我在尝试完成这项工作时遇到了麻烦 在创建时就多对多链接提出了类似的问题 看起来如果没有批量请求 就不
  • 将 CVC 传递给 stripe.createPaymentMethod JS?

    我需要 CVC 和 Expiry 的单独输入 因此我创建了 3 个 Stripe 元素 let elements stripe elements let cardNumber elements create cardNumber cardN
  • 如何使用窗口函数优化SQL查询

    这个问题与this https stackoverflow com questions 32222889 how to calculate power consumption from power records 一 我有一个包含设备功率值
  • 在 LG WebOS 电视上启用开发者模式

    我正在 LG webOS 智能电视上开发一个简单的应用程序 由于我没能从 USB 驱动器运行我的应用程序 因此我尝试使用 Eclipse IDE 中的开发人员模式 事情是 我添加了一个新的目标配置 指向物理电视 IP 当我尝试连接时 需要密
  • 独特的柱组合

    这是我的简化数据集 foo lt data frame var1 c 1 10 var2 rep 1 5 2 var3 rep 1 2 5 var4 rep 3 7 2 总共 20 个变量 foo var1 var2 var3 var4 v
  • Saml 无 Cookie 保留状态 ASP.NET CORE

    var certbase env IsDevelopment AppDomain CurrentDomain BaseDirectory var pathpfx Path Combine certbase xxxxx pfx var pat
  • 在 Hudson 通知的电子邮件中提供最新测试结果信息

    我有一个项目 有很多测试失败 所以如果我能通过电子邮件收到最新版本的失败测试数量比较 那就太好了 我需要的只是测试结果链接显示在项目页面中的信息 最新测试结果 10 次失败 2 这可能吗 我已经尝试过 email ext 插件 但它并没有告
  • 允许对对象重新排序的算法,同时只需要更新恒定数量的对象位置

    我有一大堆对象 我希望根据它们的一个属性来保持顺序 作为一个例子 我们假设一个对象可能看起来像 var myObject id c 1 position 0 有序集合的简单实现如下所示 id c 1 position 0 id c 2 po
  • 将 Azure-AD 与 dotnet core 2 web-api 中的本地用户数据库结合起来

    我正在创建一个 net core2 web api 它允许 Azure AD 中的用户使用它 该 API 是多租户的 因此来自多个 Azure AD 的用户应该能够授权 但是 也可以为没有企业 Azure AD 帐户的用户创建帐户 这些用户
  • 当遵循单一活动设计时,如何隐藏底部栏导航?

    我试图仅在几个片段中显示底部栏导航 我将其隐藏在大部分片段中 我读了官方文件 https developer android com guide navigation navigation ui listen for navigation
  • 加载指示器页面在 XPages 中完全刷新

    我的 XPage 之一有很多设计元素 根据连接速度 页面加载时间超出预期 我想创建一个指示器来显示登录用户 页面正在加载 我将其用于部分刷新 效果很好 但我无法使其进行完全刷新 我一直在寻找解决方案 我可以尝试 jquery dojo 或
  • 如何在屏障处正确同步线程

    我遇到一个问题 我很难判断应该使用哪个同步原语 我正在创建 n 个在内存区域上工作的并行线程 每个线程都分配给该区域的特定部分 并且可以独立于其他线程完成其任务 在某些时候 我需要收集所有线程的工作结果 这是使用屏障的一个很好的例子 这就是