pthreads:快速重新锁定导致的线程饥饿

2023-12-23

我有两个线程,一个在紧密循环中工作,另一个偶尔需要与第一个线程执行同步:

// thread 1
while(1)
{
    lock(work);
    // perform work
    unlock(work);
}

// thread 2
while(1)
{
    // unrelated work that takes a while
    lock(work);
    // synchronizing step
    unlock(work);
}

我的意图是线程 2 可以通过获取锁来有效地暂停线程 1 并执行必要的同步。线程 1 还可以通过解锁来暂停,如果线程 2 没有等待锁定,则重新锁定并返回工作。

我遇到的问题是互斥体不公平,因此线程1快速重新锁定互斥体并饿死线程2。我尝试使用pthread_yield,到目前为止它似乎运行良好,但我不确定它是否适用于所有系统/核心数量。有没有办法保证线程 1 始终让位于线程 2,即使在多核系统上也是如此?

处理此同步过程的最有效方法是什么?


您可以在 pthreads 互斥体之上构建 FIFO“票据锁”,如下所示:

#include <pthread.h>

typedef struct ticket_lock {
    pthread_cond_t cond;
    pthread_mutex_t mutex;
    unsigned long queue_head, queue_tail;
} ticket_lock_t;

#define TICKET_LOCK_INITIALIZER { PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER }

void ticket_lock(ticket_lock_t *ticket)
{
    unsigned long queue_me;

    pthread_mutex_lock(&ticket->mutex);
    queue_me = ticket->queue_tail++;
    while (queue_me != ticket->queue_head)
    {
        pthread_cond_wait(&ticket->cond, &ticket->mutex);
    }
    pthread_mutex_unlock(&ticket->mutex);
}

void ticket_unlock(ticket_lock_t *ticket)
{
    pthread_mutex_lock(&ticket->mutex);
    ticket->queue_head++;
    pthread_cond_broadcast(&ticket->cond);
    pthread_mutex_unlock(&ticket->mutex);
}

在这种方案下,当线程位于票证锁保护的关键部分内时,不会保留低级 pthreads 互斥体,从而允许其他线程加入队列。

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

pthreads:快速重新锁定导致的线程饥饿 的相关文章

  • 使用 GCHandle 将大型结构数组从 C# unity 脚本传递到 C++ dll 在 C++ 函数执行后崩溃

    我想从 C unity 脚本将结构数组传递给 c 本机插件 我做了如下操作 我可以访问数据 但我的应用程序在执行 c 函数后崩溃 我不知道为什么 C side StructLayout LayoutKind Sequential publi
  • 如何在 ASP.NET Core 6.0 Web API 项目中启用 cors?

    在我的 ASP NET Core 6 0 Web API 项目中配置了 CORS 但预检请求收到 http 405 错误 换句话说 不允许使用 HTTP OPTION 看起来 cors 没有启用 我见过的例子config EnableCor
  • C语言中没有循环可以打印数组吗?

    例如 在Python中 如果我们将一个列表作为数组 它会直接用一行代码打印整个数组 有什么办法可以用C语言实现同样的事情吗 简短回答 No 对表格上几乎所有问题的简短回答 用 C 语言做 X 工作能像用 Python 一样简单吗 No 长答
  • C# 实体框架我们应该使用 POCO.Id 还是仅使用 POCO 设置关系?

    我在服务方法中遇到一种情况 将 POCO 分配为另一个 POCO 的子对象无法按预期工作 我正在使用实体框架 4 public void ChangeOrderCurrency Currency currency order Currenc
  • 使用默认行为将模型绑定到接口

    我正在尝试将控制器操作绑定到接口 但仍保持默认的绑定行为 public class CoolClass ISomeInterface public DoSomething get set ISomeInterface public clas
  • PartialView Action 正在调用自身

    我有 MVC 应用程序 它用于从主视图 ProductMaster 将 ProductAreaGrid 列表显示为 PartialView 并且它将在局部视图内将 CreateProductArea 作为 PartialView 我的 Gr
  • 应用新设置时如何防止 GraphicsDevice 被丢弃?

    我的游戏窗口允许手动调整大小 这意味着它可以像任何其他普通窗口一样通过拖动其边缘来调整大小 游戏还利用了RenderTarget2D rt2d 在主 Draw 方法中设置主渲染目标 GraphicsDevice SetRenderTarge
  • 多线程 - 比单线程慢

    当我使用多个线程而不是单线程运行程序时 它会变慢 不是应该更快吗 该程序应该遍历从起始目录开始的所有目录 并查找并打印所有名为 X 的文件 代码如下 while done pthread mutex lock lock if list is
  • += 运算符在 C++ 中是如何实现的?

    这是我一直在思考的一个问题 但从未找到任何资源来说明这个问题的答案 事实上它不仅是为了 也适用于它的兄弟姐妹 即 等等 当然不是 考虑这个例子 int a 5 a 4 this will make a 9 现在考虑等效表达式 a a 4 T
  • 根据 Active Directory 策略检查密码[重复]

    这个问题在这里已经有答案了 我有一个允许用户更改其 AD 密码的前端 有没有办法获取特定用户及其属性 长度 复杂性 的密码策略 例如细粒度 有没有办法根据此特定策略检查字符串 xyz121 编辑 我不想检查活动目录中存储的当前密码 我想检查
  • 重定向 std::cout

    我需要一个类 在其对象的生命周期内将一个 ostream 重定向到另一个 ostream 经过一番修补后 我想出了这个 include
  • 确定相关词的编程方式?

    使用网络服务或软件库 我希望能够识别与词根相关的单词 例如 座位 和 安全带 共享词根 座位 但 西雅图 不会被视为匹配 简单的字符串比较对于这类事情似乎是不可行的 除了定义我自己的字典之外 是否有任何库或 Web 服务不仅可以返回单词定义
  • 使用联合对 IP 地址进行多种解释?

    在工作中 我们使用以下构造来将 IP 地址解释为 4 字节数组或 32 位整数 union IPv4 std uint32 t ip std uint8 t data 4 这很好用 但是读完这本书的第 97 章 不要使用联合来重新解释表示
  • 使用 WinAPI 连接禁用的显示设备

    我的问题是启用禁用的监视器ChangeDisplaySettingsEx 我想这不是火箭科学 但经过一番挖掘后 它看起来仍然是不可能的 我找到了一种根据找到的 Microsoft 代码示例禁用所有辅助显示器的方法here https msd
  • 在 lua 中加载 C++ 模块时出现“尝试索引字符串值”错误

    我正在尝试使用 lua 用 C 编写的函数 下面给出的是cpp文件 extern C include lua h include lauxlib h include lualib h static int add 5 lua State L
  • 在 C# 窗口应用程序中运行 C/C++ 控制台应用程序?

    现在 我想开发一个简单的应用程序 因此我决定最快的编码方式是 C NET 但现在 我很难实现我需要的功能之一 我想做的是在 C 应用程序的窗口内运行 C C 控制台应用程序 就像在虚幻前端中一样 添加一点通信方式 以便我可以为控制台应用程序
  • 如何获取运行或段落的高度

    我找到了Run or Paragraph in FlowDocument现在我需要知道HEIGHT of it i e while navigator CompareTo flowDocViewer Document ContentEnd
  • 如何创建实体集或模型而不在数据库中创建相应的表 - 实体框架

    我的 sqlserver 数据库中有一个存储过程 它返回多个结果集 我正在使用 msdn 中的以下链接从实体框架中的 SP 读取多个结果集 https msdn microsoft com en us library jj691402 v
  • 有没有办法在 C# 中仅通过文件名查找文件?

    我们现在使用绝对路径或相对路径在 C 应用程序中查找文件 如果文件位于当前工作目录下或 路径 之一下 有没有办法仅通过名称查找文件 使用绝对路径不好 使用相对路径也不够好 因为我们可能通过重命名或移动项目文件夹来更改项目结构 如果我们的代码
  • 查找和替换正则表达式问题

    感谢这里对我其他问题的所有大力帮助 我开始掌握正则表达式 但我仍然对这个一无所知 我的代码是 StreamReader reader new StreamReader fDialog FileName ToString string con

随机推荐

  • Nginx server_name regexp 不能作为变量使用

    有人告诉我为什么我仍然遇到这样的错误吗 Restarting nginx emerg unknown domain name variable configuration file etc nginx nginx conf test fai
  • Dapper MultiMap 不适用于具有 NULL 值的 splitOn

    我在尝试在包含以下内容的列上进行拆分时 在 dapper 中遇到了 MultiMaps 的问题NULL Dapper 似乎没有实例化对象 我的映射函数接收到null而不是对象 这是我的新测试 class Product public int
  • 响应宽度 Facebook 页面插件

    Facebook 推出了新的页面插件来取代 Like 框插件 文档 https developers facebook com docs plugins page plugin https developers facebook com d
  • 在 Highcharts 股票图表上将最后一点的值显示为标签或工具提示

    我在一张股票图表 HighCharts 中有多个不同比例的数据系列 我想将每个系列连接到它的轴或显示每个系列的最后一个点的值 类似于数据标签 但仅适用于每个系列的最后一个点 function container highcharts cha
  • 如何在 contenteditable div 中输入时创建一个段落?

    我正在为我的一个项目制作一个简单的编辑器 我需要使用可编辑的 div 使用contenteditable财产 我需要两个功能 输入两次后自动插入小时 创建一个段落而不是 br 进入并专注于它 所以我写了这个 带着一些灵感 这是负责的代码的一
  • 如何将 EditTextPreference 限制在范围 1024:65535

    我有一个 EditTextPreference 定义为
  • missModalViewControllerAnimated 非原子的?

    看来我有一个奇怪的时间问题 我打开 uiimagepicker 作为模态视图 当用户选择图像或我想要拍摄图像时 将其保存到变量中 然后以模态视图打开电子邮件界面 我的问题是 我在图像选择器上调用dismissModalViewControl
  • Visual Studio 2017 和 SAP Crystal Reports

    我已经下载并安装了视觉工作室 2017 社区之后我下载并安装了Crystal Report 支持包 20 v 13 0 20 2399 我打开了视觉工作室2017并创建一个新项目 然后右键单击我的项目 然后单击添加项目 我寻找水晶报告 rp
  • 提升文件末尾序列化

    我使用 Boost 将多个对象序列化为二进制存档 当从 a 读回这些对象时binary iarchive 有没有办法知道存档中有多少对象 或者只是检测存档结尾的方法 我发现的唯一方法是使用 try catch 来检测流异常 提前致谢 我可以
  • ggplot:如何根据相对于绘图宽度的边距来换行标题文本

    当使用绘图时ggplot2 如何将标题文本换行以适应相对于绘图整个宽度的边距 library ggplot2 library stringr my title lt c reltively long sentences that norma
  • 在 Objective-C 框架中使用 Swift 闭包

    我正在使用 MCSwipeTableViewCell 框架来实现可滑动的 tableviewcell 内的完成块之一cellForRowAtIndexPath函数看起来像这样 cell setSwipeGestureWithView che
  • 在 Xamarin Forms 中加载查看内容时显示活动指示器

    有没有办法在页面内容视图渲染或加载时显示活动指示器 我问这个是因为当我在页面中有很多控件并且我想导航到该页面时 需要几秒钟的时间到页面 所以我想知道是否有一种方法可以即时导航页面 并且当页面出现时显示加载内容的活动指示器 以及当内容加载时显
  • JavaFX的任务似乎消耗异常。这是一个错误还是一个功能?

    考虑这段代码 Thread setDefaultUncaughtExceptionHandler Thread t Throwable e gt System out println An exception occurred set th
  • 如何取消并重新启动 C# 任务 [重复]

    这个问题在这里已经有答案了 我有一个长时间运行 长时间间隔的轮询过程 我需要能够强制更新并重新启动轮询 我想到的最明显的事情是取消轮询任务 并开始一个新的任务 因为初始循环总是更新 我试图找出最好的方法来做到这一点 使用 Operation
  • 搜索 API 中的模糊搜索

    Azure 搜索 api 提供了一个模糊参数来提供建议 像这样 https blssuggestions search windows net indexes cities docs suggest api version 2015 02
  • matlab中的递归函数

    我如何在matlab中编写递归函数 它基本上是一个马尔可夫链 我尝试为它编写一个伪代码 并且是新的MATLAB 该函数是这样的 P Probability x status 0 1 Dij probability to pick a sit
  • 为什么我的代码行在等待之后没有被调用?

    我对以下代码有问题 firebase login 返回一个 Promise 我了解到 当我之前输入 await 时 Javascript 会等待 Promise 交付 然后继续下一行 I 但下一行似乎永远不会被触发 我究竟做错了什么 它也不
  • GetProcessMemoryInfo PROCESS_MEMORY_COUNTERS_EX.PrivateUsage 始终为 0

    我在用着获取进程内存信息 https msdn microsoft com en us library windows desktop ms683219 v vs 85 aspx函数通过 PID 确定进程内存使用情况 与常规的PROCESS
  • 如何在打包程序提供脚本中传递参数?

    我正在努力将输入参数传递给打包程序配置脚本 我尝试过各种选择但没有喜悦 目标是我的provision sh应该接受我在打包器构建期间发送的输入参数 packer build var role abc test json 我能够在 json
  • pthreads:快速重新锁定导致的线程饥饿

    我有两个线程 一个在紧密循环中工作 另一个偶尔需要与第一个线程执行同步 thread 1 while 1 lock work perform work unlock work thread 2 while 1 unrelated work