Python 3.1.2
我遇到了由 multiprocessing.Process 生成的两个线程之间的变量共享问题。这是一个简单的bool变量,它应该确定线程是否应该运行还是应该停止执行。下面是三种情况下显示的简化代码(但使用与原始代码相同的机制):
我想要了解为什么它以这种方式工作而不是另一种方式。 (即为什么第2点不起作用,因为我认为应该这样做。)
测试是从python的解释器完成的:
from testclass import *
d = TestClass()
d.start()
d.stop()
import threading
import time
import queue
import multiprocessing
class TestClass(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.q = queue.Queue(10)
self.is_running = True
self.sema = threading.Semaphore()
def isRunning(self):
self.sema.acquire()
print ("Am I running?", self.is_running)
z = self.is_running
self.sema.release()
return z
def stop(self):
self.sema.acquire()
self.is_running = False
print("STOPPING")
self.sema.release()
def reader(self):
while self.isRunning():
print("R] Reading!")
try:
data = self.q.get(timeout=1)
except:
print("R] NO DATA!")
else:
print("R] Read: ", data)
def writer(self):
while self.isRunning():
print("W] Writing!")
self.q.put(time.time())
time.sleep(2)
def run(self):
tr = threading.Thread(target=self.reader)
tw = threading.Thread(target=self.writer)
tr.start()
tw.start()
tr.join()
tw.join()
import threading
import time
import queue
import multiprocessing
class Test(multiprocessing.Process):
def __init__(self):
multiprocessing.Process.__init__(self)
self.q = queue.Queue(10)
self.is_running = True
self.sema = threading.Semaphore()
def isRunning(self):
self.sema.acquire()
print ("Am I running?", self.is_running)
z = self.is_running
self.sema.release()
return z
def stop(self):
self.sema.acquire()
self.is_running = False
print("STOPPING")
self.sema.release()
def reader(self):
while self.isRunning():
print("R] Reading!")
try:
data = self.q.get(timeout=1)
except:
print("R] NO DATA!")
else:
print("R] Read: ", data)
def writer(self):
while self.isRunning():
print("W] Writing!")
self.q.put(time.time())
time.sleep(2)
def run(self):
tr = threading.Thread(target=self.reader)
tw = threading.Thread(target=self.writer)
tr.start()
tw.start()
tr.join()
tw.join()
import threading
import time
import queue
import multiprocessing
class TestClass(multiprocessing.Process):
def __init__(self):
multiprocessing.Process.__init__(self)
self.q = queue.Queue(10)
self.is_running = multiprocessing.Value("b", True)
self.sema = threading.Semaphore()
def isRunning(self):
self.sema.acquire()
print ("Am I running?", self.is_running)
z = self.is_running.value
self.sema.release()
return z
def stop(self):
self.sema.acquire()
self.is_running.value = False
print("STOPPING")
self.sema.release()
def reader(self):
while self.isRunning():
print("R] Reading!")
try:
data = self.q.get(timeout=1)
except:
print("R] NO DATA!")
else:
print("R] Read: ", data)
def writer(self):
while self.isRunning():
print("W] Writing!")
self.q.put(time.time())
time.sleep(2)
def run(self):
tr = threading.Thread(target=self.reader)
tw = threading.Thread(target=self.writer)
tr.start()
tw.start()
tr.join()
tw.join()
答案 0 :(得分:0)
线程都是同一进程的一部分,因此它们共享内存。另一个结果是线程不能由不同的cpu同时执行,因为一个进程只能被一个cpu接收。
进程具有单独的内存空间。一个cpu可以运行一个进程,而另一个cpu运行另一个进程。需要特殊的结构让流程合作。
答案 1 :(得分:0)
在第2点,父进程和子进程都有自己的is_running
副本。当您在父进程中调用stop()
时,它只会修改父进程中的is_running
而不会修改子进程中的{{1}}。 multiprocessing.Value工作的原因是它的内存在两个进程之间共享。
如果您需要可识别进程的队列,请使用multiprocessing.Queue。