我以前使用过该threading.Thread模块。现在我正在使用concurrent.futures-> ThreadPoolExecutor。以前,我使用以下代码退出/终止/完成一个线程:
def terminate_thread(thread):
"""Terminates a python thread from another thread.
:param thread: a threading.Thread instance
"""
if not thread.isAlive():
return
exc = ctypes.py_object(SystemExit)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
ctypes.c_long(thread.ident), exc)
if res == 0:
raise ValueError("nonexistent thread id")
elif res > 1:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread.ident, None)
raise SystemError("PyThreadState_SetAsyncExc failed")
Run Code Online (Sandbox Code Playgroud)
这似乎不适用于期货界面。这里的最佳做法是什么?只是return?我的线程正在控制 Selenium …
有没有办法以编程方式中断Python的raw_input?具体来说,我想向用户提示,但也要监听套接字描述符(例如使用select)并中断提示,输出内容,如果数据进入套接字,则重新显示提示.
使用raw_input而不是简单地在sys.stdin上执行select的原因是我想使用readline模块为提示提供行编辑功能.
我希望在运行0.5秒后超时一段特定的python代码.所以我打算在0.5秒后引发一个异常/信号,并优雅地处理它并继续其余的代码.
在python我知道signal.alarm()可以设置整数秒的警报.是否有任何替代方案,我们可以在0.5秒后生成警报.signal.setitimer()正如其他帖子中所建议的那样在python2.4中不可用,我需要使用python2.4来达到这个目的吗?
我使用以下代码启动一个线程.
t = thread.start_new_thread(myfunction)
Run Code Online (Sandbox Code Playgroud)
我怎么t能从另一个线程中杀死线程.所以基本上在代码方面,我希望能够做到这样的事情.
t.kill()
Run Code Online (Sandbox Code Playgroud)
请注意,我使用的是Python 2.4.
我想用
scalaz.concurrent.Task实现我的异步处理.我需要一个函数(Task[A], Task[B]) => Task[(A, B)]来返回一个工作如下的新任务:
Task[A]并Task[B]等待结果;你会如何实现这样的功能?
如果需要,如何正确和干净地终止python程序?sys.exit()不能可靠地执行这个功能,因为它只是终止它被调用的线程,exit()并且quit()不应该被使用,除了终端窗口,raise SystemExit有相同的问题sys.exit()和不好的做法,并os._exit()立即杀死一切,不清理,会导致残差问题.
有没有一种方法可以一直杀死程序和所有线程,无论它在哪里被调用,同时还在清理?
该线程详细讨论了为什么终止线程不是一个好主意。当我们谈论一个实际的计划时,我同意。我正在为几个组件编写单元测试以及它们之间的一些集成测试。有些需要线程。当测试失败时,某些线程保持打开状态,并锁定在.get()队列的调用中。这会导致整个测试套件陷入困境并且不完整。我正在运行ptw(pytest watch) 或 pytest 的自定义循环,以inotifywait监视文件中的更改以重新运行套件。
当所有测试完成后,我希望套件杀死任何剩余的线程以完成循环,而不是卡在由于测试失败而刚刚打开的某个线程上。这可能吗?
我正在运行一段 python 代码,其中多个线程通过线程池执行程序运行。每个线程都应该执行一项任务(例如获取网页)。我希望能够做的是终止所有线程,即使其中一个线程失败。例如:
with ThreadPoolExecutor(self._num_threads) as executor:
jobs = []
for path in paths:
kw = {"path": path}
jobs.append(executor.submit(start,**kw))
for job in futures.as_completed(jobs):
result = job.result()
print(result)
def start(*args,**kwargs):
#fetch the page
if(success):
return True
else:
#Signal all threads to stop
Run Code Online (Sandbox Code Playgroud)
有可能这样做吗?除非所有线程都成功,否则线程返回的结果对我来说是无用的,因此即使其中一个失败,我也想节省其余线程的一些执行时间并立即终止它们。实际代码显然正在执行相对冗长的任务,有几个故障点。
我一直在尝试为控制某些硬件的库编写一个交互式包装器(用于ipython).有些调用对IO很重要,因此并行执行任务是有意义的.使用ThreadPool(几乎)很好地工作:
from multiprocessing.pool import ThreadPool
class hardware():
def __init__(IPaddress):
connect_to_hardware(IPaddress)
def some_long_task_to_hardware(wtime):
wait(wtime)
result = 'blah'
return result
pool = ThreadPool(processes=4)
Threads=[]
h=[hardware(IP1),hardware(IP2),hardware(IP3),hardware(IP4)]
for tt in range(4):
task=pool.apply_async(h[tt].some_long_task_to_hardware,(1000))
threads.append(task)
alive = [True]*4
Try:
while any(alive) :
for tt in range(4): alive[tt] = not threads[tt].ready()
do_other_stuff_for_a_bit()
except:
#some command I cannot find that will stop the threads...
raise
for tt in range(4): print(threads[tt].get())
Run Code Online (Sandbox Code Playgroud)
如果用户想要停止进程或者出现IO错误,则会出现问题do_other_stuff_for_a_bit().按Ctrl+ C停止主进程,但工作线程继续运行,直到当前任务完成.
有没有办法阻止这些线程,而不必重写库或让用户退出python? pool.terminate()而pool.join()我在其他例子中看到的似乎并没有做到这一点.
实际例程(而不是上面的简化版本)使用日志记录,虽然所有工作线程都在某个时刻关闭,但我可以看到它们开始运行的进程一直持续到完成(并且硬件我可以通过查看看到它们的效果穿过房间).
这是在python 2.7中.
更新:
解决方案似乎是切换到使用multiprocessing.Process而不是线程池.我试过的测试代码是运行foo_pulse:
class …Run Code Online (Sandbox Code Playgroud) 我在这里看到了一些示例,例如使用一个Event停止线程,我认为布尔标志可以完成这项工作.
class MyThread(threading.Thread):
def __init__(self):
self._please_stop = threading.Event()
def run(self):
while not self._please_stop.is_set():
[...]
def stop(self):
self._please_stop.set()
Run Code Online (Sandbox Code Playgroud)
class MyThread(threading.Thread):
def __init__(self):
self._please_stop = False
def run(self):
while not self._please_stop:
[...]
def stop(self):
self._please_stop = True
Run Code Online (Sandbox Code Playgroud)
Event在这里使用一个有什么好处?它的wait方法没有使用.是什么让它比布尔标志更好?
如果Event在多个线程之间共享相同的内容,我可以看到这一点,否则,我不明白.
这个邮件列表线程表明它Event会更安全,但我不明白为什么.
更准确地说,我不明白这两段:
如果我正确理解了GIL,它会同步对Python数据结构的所有访问(例如我的布尔'终止'标志).如果是这种情况,为什么还要为此目的使用threading.Event呢?
GIL是一个实现细节,依靠它来为您同步事物不是未来的.你可能会有很多警告,但使用threading.Event()并不是更难,而且从长远来看它更正确,更安全.
我同意使用Event添加几乎没有开销,所以我可以坚持,但我想了解标志方法的局限性.
(我正在使用Python3,所以我不关心Python2的限制,如果有的话,尽管这些在这里完全值得一提.)
python ×9
concurrency ×2
python-3.x ×2
alarm ×1
exit-code ×1
input ×1
python-2.4 ×1
readline ×1
scala ×1
scalaz ×1
signals ×1
task ×1
testing ×1
threadpool ×1
timeout ×1