multithreading - 工作线程,具有特定“颜色”的作业,每种颜色只能运行一个作业,我需要什么同步原语?
问题描述
我有 N 个工作线程和一个作业队列。当工作线程空闲时,它会从队列中挑选一个作业并开始运行它。到目前为止,很容易。
然而,我的工作有一个属性,我称之为“颜色”。决不能同时运行两个相同颜色的作业。
例如,假设有 2 个线程,一个正在运行红色作业,另一个处于空闲状态。空闲线程查看队列,但它不能选择红色作业(因为如果这样做,将有两个红色作业正在运行,这是不允许的)。如果队列中有一个蓝色作业,它可以运行它。如果队列中只有红色作业,则空闲线程必须等到另一个线程完成。然后两个线程都处于空闲状态,它们必须选择不同颜色的作业来运行,如果到那时队列中仍然只有红色作业,则必须保持空闲状态。
我的问题是我应该在这里使用什么同步原语。我考虑将队列分组为颜色,并且可以将互斥锁附加到每个颜色组,但后来我被困在如何使用这些互斥锁上。(实际的程序是使用 pthreads 用 OCaml 编写的,因此它可以访问通常的 pthread 原语和构建在 pthreads 之上的原语)。
这听起来像是一个相当不寻常的案例,但它与现实世界的问题有关:我正在编写一个依赖运行程序(想想:“make”)。如果两个配方以相同的输出文件(“颜色”)为目标,则它绝不能并行运行两个配方(“作业”)。
解决方案
有一些“明显”的解决方案。
您可以有一个“红色”线程和一个“蓝色”线程,分别为“红色”和“蓝色”队列提供服务。由于您永远不想拥有多个正在进行的“红色”工作,因此拥有线程池不会给您带来任何好处。
如果由于某种原因您仍想在线程池上多路复用“红色”作业,您仍然可以使用单独的“红色”和“蓝色”队列,以及指示相应颜色作业是否正在进行的布尔标志。然后一个空闲线程将遍历所有非空队列并选择第一个具有
in_progress == false
.您可以将单个队列与一组布尔标志组合在一起。现在空闲线程将遍历队列,直到找到一个工作
in_progress[color] == false
并选择它。
推荐阅读
- python-3.x - 以英语打印当前日期
- groovy - 在 jenkins pipline sh 步骤中使用 sed 转义引号
- c++ - 使用带括号表达式的逗号运算符示例
- c# - 使用 Apache 作为反向代理时,ASP.NET Core Razor 无法设置 cookie
- azure - 如何将放置在 azure 文件存储中的 .csv 文件的内容复制到 powershell 变量?
- mysql - mysql更新脚本不更新数据库
- webpack-4 - Webpack 加载相对于主输出文件的分割块
- java - Java 中如何管理 Metaspace 和 Native Area 内存?
- php - 在 Docker 文件中自定义安装
- clickatell - Clickatell 使用 Rest API 获取路由错误