工作线程的基本思想:
class Worker(threading.Thread):def __init__(self,queue): self.queue = queue # more code heredef run(self): while True: try: job = self.queue.get() #do some work proc = subprocess.run("myprogram",timeout=my_timeout) #do some more things except TimeoutExpired: #do some administration self.queue.add(job)
然而:
>此消费者应该能够从前端(主线程)接收某种信号,它应该停止当前作业,而是处理队列中的下一个作业(保存当前作业的状态并将其添加到最后再次排队).这可以(并且很可能)在subprocess.run()上被阻止时发生.
>可以简单地杀死子进程(执行的程序在文件中保存了sme状态)但是工作线程需要对被杀死的作业进行一些管理,以确保稍后可以恢复它.
>可以有多个这样的工作线程.
>信号处理程序不是一个选项(因为它们总是由主线程处理,这是一个网络服务器,不应该为此烦恼).
>有一个事件循环,其中进程主动轮询事件(例如子出口,超时发生或中断事件)在这种情况下不是真正的解决方案,而是一个丑陋的黑客.这些作业性能很重,并且不需要持续的上下文切换.
我应该使用哪些同步原语来中断此线程或确保它以阻塞方式同时等待多个事件?
解决方法 我认为你不小心掩饰了一个简单的解决方案:你的第二个要点是你有能力杀死在子进程中运行的程序.请注意subprocess.call returns the return code of the subprocess.这意味着您可以让主线程终止子进程,只需检查返回代码以查看是否需要进行任何清理.更好的是,您可以使用 subprocess.check_call,如果返回码不是0,将为您引发异常.我不知道您正在使用什么平台,但在linux上,被杀死的进程通常不会返回0如果他们被杀了它可能看起来像这样:
class Worker(threading.Thread):def __init__(self,queue): self.queue = queue # more code heredef run(self): while True: try: job = self.queue.get() #do some work subprocess.check_call("myprogram",timeout=my_timeout) #do some more things except (TimeoutExpired,subprocess.CalledProcessError): #do some administration self.queue.add(job)
请注意,如果您使用的是Python 3.5,则可以使用subprocess.run,并将check参数设置为True.
如果你强烈需要处理工作程序在没有运行子进程时需要中断的情况,那么我认为你将不得不使用轮询循环,因为我不认为你的行为Python中的线程支持查找.您可以使用threading.Event对象将“现在停止工作”伪信号从主线程传递给工作线程,并让工作人员定期检查该事件对象的状态.
如果您愿意考虑使用多个处理代替线程,请考虑切换到multiprocessing module,这将允许您处理信号.产生完整的子进程而不是线程有更多的开销,但你实际上是在寻找类似信号的异步行为,我不认为Python的线程库支持这样的东西.但有一个好处是,您可以从Global Interpreter Lock(pdf链接)中解脱出来,因此如果您的工作进程(以前的线程)正在执行任何cpu密集型 *** 作,您实际上可能会看到一些速度优势.
总结以上是内存溢出为你收集整理的Python – 通知在子进程上阻塞的另一个线程全部内容,希望文章能够帮你解决Python – 通知在子进程上阻塞的另一个线程所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)