提问人:orbita 提问时间:10/13/2022 更新时间:10/13/2022 访问量:124
在单独的线程中快速执行 IO 操作
Fast IO operations in a seperate thread
问:
我有一组与我的程序通信的工具,我想将通信放在一个单独的线程中。
IO 非常慢(每个仪器每个项目 ~100 毫秒),我需要将它们的结果值记录在一个共享数组(最后 N 个值)中并保存到一个文件中,并尽快进行重复测量。有些仪器“制定”响应的速度很慢,因此一些读数可以同时完成,但读数需要近似同步(即每行读数 1 个时间戳)
我希望这一切都在一个单独的线程中完成,这样计时就不会被主线程中发生的计算等中断,但主线程应该能够访问数组。
理想情况下,我应该能够运行一些,并且无需进一步交互即可开始。daq.start()
什么是“pythonic”方法?我一直在阅读有关异步、线程和多处理的文章,但我不清楚哪个是合适的。
在 c++ 中,我会启动 thread1,它只会按顺序将测量值记录到缓存数组中。Thread2 会在可以获得锁时将该缓存刷新到主共享数组中。同时,它会将其写入输出文件。通过跟踪正在读取的索引范围,锁定冲突将很少见(但重要的是,当它们发生时不会中断DAQ)
答:
这里的正确答案是线程,这不是意见。
与硬件的通信是使用 DLL 中实现的驱动程序完成的,当 python 调用 DLL 时,它会删除 GIL,因此线程可以在后台执行,而 python 解释器本身的开销尽可能少。
应该进行适当的同步,如果使用线程写入文件,则包括线程锁定,但是在写入文件时,线程将删除 GIL,并且它们在 Python 解释器上仍然几乎没有开销。
以上两者都不适用于 asyncio,它是为异步网络而不是硬件而设计的。
对于实现来说,线程池通常是最 python 的方式,你只需生成与你连接的仪器数量一样多的 worker,然后让它们完成它们的工作。
由于您没有使用任何 Asyncio 功能,因此您应该将 Multiprocesing.ThreadPool 与 OR 一起使用,并且线程模块中的线程锁用于写入磁盘,如果要在所有线程之间同步每个帧,也存在障碍。apply_async
imap_unordered
评论