所以最近我遇到了以下问题:我必须创建一个处理请求的服务器,以便在主进程使用此值时更新某些值。 所以这里,服务器处理功能在子进程中,我不能在我想要的时候停止它。
为了测试threading.Thread
或multiprocessing.Process
之间我的问题的最佳解决方案,我在以下程序中做了以下几点:
import multiprocessing
import time
import threading
class SubProcess(multiprocessing.Process):
def __init__(self, source):
self.source = source
super(SubProcess, self).__init__()
def run(self):
while 1:
time.sleep(1) # Waiting for request...
self.source.somevar["anotherkey"].append(5)
print "My subprocess : ", id(self.source), id(self.source.somevar), self.source.somevar
class SubThread(threading.Thread):
def __init__(self, source):
self.source = source
super(SubThread, self).__init__()
def run(self):
while 1:
time.sleep(1) # Waiting for request...
self.source.somevar["anotherkey"].append(5)
print "My subthread : ", id(self.source), id(self.source.somevar), self.source.somevar
class Source:
def __init__(self):
self.somevar = {"akey": "THE key", "anotherkey": [5]}
def start_process(self):
self.process = SubProcess(self)
self.process.start()
def stop_process(self):
self.process.terminate()
def start_thread(self):
self.thread = SubThread(self)
self.thread.start()
def stop_thread(self):
# self.thread.stop() # What the hell should i put here
pass
s = Source()
s.start_process()
time.sleep(2)
print "End : ", id(s), id(s.somevar), s.somevar
s.stop_process()
s.start_thread()
time.sleep(2)
print "End : ", id(s), id(s.somevar), s.somevar
s.stop_thread() # Obviously, thread never ends...
所以threading.Thread
修改了原始s.somevar
,但我无法阻止它,而multiprocessing.Process
没有修改原s.somevar
,但我可以停止它
我正在寻找一个可以停止线程的解决方案(使用SIGTERM),线程可以使用标准库修改原始类Source
,。有没有解决方案?
答案 0 :(得分:1)
要杀死线程,你需要在子线程和主线程之间做一些合作。使用示例代码,您可以使用threading.Event
:
class SubThread(threading.Thread):
def __init__(self, source):
self.source = source
self.should_stop = threading.Event()
super(SubThread, self).__init__()
def run(self):
while not self.should_stop.wait(1):
#time.sleep(1) # No need to sleep, since we're waiting for 1 second above.
self.source.somevar["anotherkey"].append(5)
print "My subthread : ", id(self.source), id(self.source.somevar), self.source.somevar
def stop(self):
""" Call this to abort the thread. """
self.should_stop.set()
这并不像process.terminate()
那样立即终止,因为在线程停止之前你必须实际调用should_stop.wait()
。
要使SubProcess
正常工作,您需要使用进程安全的共享变量。 multiprocessing
模块为此提供multiprocessing.Manager
;它允许您在管理器进程中创建共享变量。你正在更新dict的方式实际上有点难以正确处理,因为在Proxy
中从Manager
对象中更改可变值的一些限制(请参阅请注意here)。您必须明确地将更新的列表重新分配给dict才能正确更新dict:
class SubProcess(multiprocessing.Process):
def __init__(self, source):
self.source = source
super(SubProcess, self).__init__()
def run(self):
while 1:
time.sleep(1) # Waiting for request...
# Can't do this with a Manager.dict
#self.source.somevar["anotherkey"].append(5)
# Do this instead. You'd need to do it with SubThread.run, too.
l = self.source.somevar["anotherkey"]
l.append(5)
self.source.somevar["anotherkey"] = l
print "My subprocess : ", id(self.source), id(self.source.somevar), self.source.somevar
class Source:
def __init__(self):
self.m = multiprocessing.Manager()
# somevar is now process-safe.
self.somevar = self.m.dict({"akey": "THE key", "anotherkey": [5]})
# The rest is the same
答案 1 :(得分:0)
不,没有。有关选项的讨论,请参阅Is there any way to kill a Thread in Python? - 但这些是合作的!如果无法做到这一点,请使用多处理+消息在本地更新状态副本。