Python 当其他应用程序正在运行时,线程运行速度不够快
我正在使用线程模块在后台运行一个函数,同时执行脚本的其余部分。线程函数包含一个for循环,它等待外部5伏触发器,每15毫秒触发一次,然后继续下一个循环迭代 当这段代码是PC上唯一运行的东西时,一切都按预期运行。但是,当我运行其他必要的应用程序时,会给cpu带来压力,线程函数中的For循环只会执行,并在大约90%的时间内在15毫秒的时间窗口内继续到下一次迭代 线程化函数的输入是ctypes指针列表 我在一个类中运行线程函数,所以使用多处理是很棘手的(如果这有帮助的话,我不确定) 我试图用这两个类的框架来说明下面的问题Python 当其他应用程序正在运行时,线程运行速度不够快,python,python-multiprocessing,python-multithreading,Python,Python Multiprocessing,Python Multithreading,我正在使用线程模块在后台运行一个函数,同时执行脚本的其余部分。线程函数包含一个for循环,它等待外部5伏触发器,每15毫秒触发一次,然后继续下一个循环迭代 当这段代码是PC上唯一运行的东西时,一切都按预期运行。但是,当我运行其他必要的应用程序时,会给cpu带来压力,线程函数中的For循环只会执行,并在大约90%的时间内在15毫秒的时间窗口内继续到下一次迭代 线程化函数的输入是ctypes指针列表 我在一个类中运行线程函数,所以使用多处理是很棘手的(如果这有帮助的话,我不确定) 我试图用这两个类的
import ctypes
import Write_transient_frames_func
import SendScriptCommands
from threading import Thread
class SlmInterface():
def __init__(self,sdk):
self.sdk = sdk
def precalculate_masks(self, mask_list):
'''takes input mask_list, a list of numpy arrays containing phase masks
outputs pointers to memory location of masks
'''
#list of pointers to locations of phase mask arrays in memory
mask_pointers = [mask.ctypes.data_as(POINTER(c_ubyte)) for mask in mask_list]
return mask_pointers
def load_precalculated_triggered(self, mask_pointers):
okay = True
print('Ready to trigger')
for arr in mask_pointers:
okay = self.Write_transient_frames_func(self.sdk, c_int(1), arr, c_bool(1), c_bool(1), c_uint(0))
assert okay, 'Failed to write frames to board'
print('completed trigger sequence')
class Experiment():
def run_experiment(self, sdk, mask_list):
slm = SlmInterface(sdk)
#list of ctypes pointers
mask_pointers = slm.precalculate_masks(mask_list)
##the threaded function
slm_thread = Thread(target=slm.load_precalculated_triggered, args = [mask_pointers])
slm_thread.start()
time.sleep(0.1)
# this function loads the 15ms trigger sequences to the hardware and begins the sequence
self.mp_output = SendScriptCommands()
有可能加快线程函数的执行速度吗?并行处理会有帮助吗?还是我基本上受到cpu的限制?不幸的是,Python可能无法做得更好。Python有一个漏洞,这意味着多线程不像在其他语言中那样工作。您应该知道,Python中的多线程使应用程序运行速度变慢。好的替代方法是使用asyncio,因为它允许在一个线程内协作多任务处理(->操作系统不需要实际切换线程->开销减少->执行速度加快)。如果你以前没用过,一开始用起来有点怪,但实际上它真的很好
然而,您的任务似乎确实受到cpu的限制。因此,可能唯一的选择是使用python进行多处理。可能python并不是真正的罪魁祸首。关键是,对于通用、抢占式、多用户操作系统,您将无法保证连续运行,足以捕获任何15毫秒的触发器。CPU的分配量通常为数十毫秒,操作系统可以(也将)根据CPU负载让线程或多或少地运行,努力为每个进程分配公平的可用CPU时间 您可以增加线程的优先级,要求它具有高于其他线程的优先级,或者在极端情况下,将其更改为实时优先级,让它无限期占用CPU(如果出现问题,可能会挂起系统)
但实际上,解决方案是在较低级别上处理此问题,无论是在内核模式还是在硬件中。如果您不能错过信号,则从用户模式以这些速率进行轮询是不可取的,因此您可能应该调查您的硬件/驱动程序是否提供了更高级别的接口,例如,触发器上的中断(例如转换为解锁某个阻塞调用,或生成信号或其他内容) 您正在使用并行处理。线程由操作系统控制。我认为你要求15毫秒的响应时间是不现实的。谢谢,有没有其他方法可以让我在后台运行load_precalculated_triggered函数,然后继续脚本的其余部分?我以前也遇到过同样的问题,我发现我的线程有while循环运行,消耗了cpu的能量,后来我发现我必须在循环中添加'time.sleep(0.1)'作为延迟时间,以便让其他线程有时间工作,令人惊讶的是,我的cpu使用率正常,线程运行速度超快,注意:我的应用程序是一个下载管理器,它可以在一次下载中生成100多个并发线程,并且可以同时启动并发下载,而不会出现速度下降。在试图捕获每15毫秒发生一次的信号的线程中休眠100毫秒只会使问题变得更糟。现在你每6次都会丢失~5个信号-很好的工作!