2. 并行控制基础

在多仪器并行控制与同步系统中,所有性能问题最终都会落到一个根本问题上:多个仪器动作到底是按什么顺序、以什么方式被组织和执行的。如果对“串行、并行、并发、进程、线程、任务调度”这些基础概念理解模糊,就很容易写出“看起来并行、实际串行”的控制程序,导致多台仪器无法真正同时工作,同步精度也无法保证。本节从执行模型出发,把这些概念一次讲清楚。

一、串行与并行:执行时间轴上的两种基本形态

串行是指多个任务按先后顺序依次执行,前一个任务完成后,后一个任务才开始。它的时间轴是一条直线,总耗时等于各任务耗时之和。例如依次设置三台电源的电压,再依次读取三台万用表的读数,就是典型串行。

并行是指多个任务在同一时间段内真正同时推进。它的时间轴是多条并行的线,总耗时取决于最慢的那条分支。例如三台仪器各自独立完成“配置—触发—采集”流程,互不等待,就是并行。

两者的关键差别不在“代码写了几行”,而在于是否存在等待重叠。串行时,等待时间无法被利用;并行时,一台仪器等待稳定期的同时,另一台仪器可以继续工作,从而把总时间压缩到接近最长单任务的时间。

判断一段控制逻辑是串行还是并行,最直接的方法是画出时间轴:如果所有动作首尾相接、没有重叠区间,就是串行;如果存在两个以上动作在时间上重叠,就是并行。

二、并发与并行:容易混淆的一对概念

并发强调“多个任务在宏观上同时被处理”,但在微观上它们可能交替执行。单核 CPU 通过快速切换,让多个任务轮流占用处理器,用户感觉它们在同时进行,这就是并发。并行则强调“多个任务在物理上真正同时执行”,通常需要多核 CPU、多通道采集卡或多台独立仪器等硬件资源支撑。

可以这样理解:并发是任务组织方式,并行是物理执行方式。并发不一定并行,但并行一定包含并发。在多仪器控制中,即使只有一块单核控制器,也可以通过并发调度让多台仪器“看起来同时工作”;而要让它们真正同时动作,则需要并行资源,例如多线程、多进程或多台带独立触发总线的仪器。

串行 / 并发 / 并行 时间轴对比 串行 仪器A 仪器B 仪器C 总耗时 = A+B+C 并发 A B C A 单核交替执行,宏观同时 并行 仪器A 独立执行 仪器B 独立执行 仪器C 独立执行 总耗时 ≈ 最慢分支 时间 →

三、进程与线程:资源与执行的基本单位

进程是操作系统进行资源分配的基本单位。每个进程拥有独立的地址空间、文件句柄、设备句柄等资源。进程之间相互隔离,一个进程崩溃通常不会直接影响另一个进程,因此稳定性好,但创建和切换开销较大,进程间通信也需要专门机制。

线程是操作系统进行调度的基本单位。同一进程内的多个线程共享该进程的地址空间和资源,因此创建、切换和通信开销都更小,适合需要频繁交互、共享数据的场景。但共享也带来风险:多个线程同时读写同一变量或同一仪器句柄时,可能产生竞态条件,必须用锁、队列或原子操作加以保护。

对比项进程线程
资源分配独立地址空间与资源共享所属进程资源
创建/切换开销较大较小
隔离性强,互不影响弱,一个线程崩溃可能拖垮进程
通信方式管道、共享内存、消息队列等直接读写共享变量,需同步保护
多仪器控制适用场景仪器驱动相互独立、需强隔离多仪器共享配置、需频繁协同

四、任务调度:让多个仪器动作有序推进

任务调度决定“哪个任务在什么时候占用执行资源”。常见策略包括:先来先服务、优先级调度、时间片轮转、以及事件驱动的异步调度。在多仪器并行控制中,调度器通常需要同时考虑三类约束:

  • 时间约束:某些仪器必须在指定时刻触发,例如同步采集的硬触发。
  • 资源约束:同一通信总线、同一电源通道不能被两个任务同时占用。
  • 依赖约束:仪器 B 的采集必须等待仪器 A 的激励建立完成。

一个实用的做法是把每台仪器的控制流程拆成若干“任务单元”,由调度器统一排队,再根据优先级和资源占用情况分派执行。下面是一个简化的任务描述示例:

task_list = [
  {"id": "PSU_SET",  "instrument": "PSU1", "action": "set_voltage", "value": 5.0, "priority": 1},
  {"id": "DMM_READ", "instrument": "DMM1", "action": "read",        "delay_ms": 200, "priority": 2},
  {"id": "SCOPE_TRIG","instrument": "SCOPE1","action": "trigger",    "priority": 1},
  {"id": "AWG_OUT",  "instrument": "AWG1", "action": "output_on",   "priority": 3}
]
# 调度器按 priority 排序,并检查同一总线资源是否冲突

五、案例场景:三台仪器同步采集

假设需要让信号源输出激励、电源上电、示波器采集三者协同。若采用串行方式:先开电源,等待 500 ms 稳定,再开信号源,等待 100 ms,最后启动示波器,总耗时约 600 ms 以上,且触发时刻分散。若采用并行加调度方式:电源、信号源、示波器分别由独立线程或进程管理,主调度器只负责在关键节点发出同步触发,则总耗时接近最慢分支,且三台仪器的动作时间差可控制在微秒级。

在多仪器系统中,优先把“等待类操作”(如稳定延时、量程切换、采集等待)并行化,把“共享资源操作”(如同一总线上的读写)串行化,这样既能压缩总时间,又能避免资源冲突。

六、常见误区与复盘

  • 误区一:用了多线程就等于并行。如果多个线程都在等待同一把锁,实际执行仍然是串行的,甚至比单线程更慢。
  • 误区二:并发数越多越好。线程或进程过多会带来调度开销和资源争用,反而降低同步精度。
  • 误区三:忽略仪器本身的执行时间。软件并行不等于仪器并行,仪器内部量程切换、稳定建立仍需真实时间。
  • 误区四:不做同步保护。多个线程同时操作同一仪器句柄,可能导致命令交错、响应错位,必须加锁或使用命令队列。
复盘时建议记录每个任务的“发起时刻、完成时刻、等待原因”。如果发现大量时间花在等待锁或等待总线,说明并发设计需要调整;如果发现任务时间轴几乎没有重叠,说明并行并未真正生效。

掌握串行与并行、并发与并行的区别,理解进程与线程的资源和调度差异,并建立任务调度的基本思维,是后续实现多仪器精确同步的前提。只有先看清执行模型,才能在代码层面做出正确的并行化决策。