我在测试多处理模块时有点困惑。
让我们模拟一个数字定时器。代码看起来像这样:
start=datetime.now()
while True:
now=datetime.now()
delta=now-start
s = delta.seconds + delta.microseconds/1E6
print s
time.sleep(1)
正确返回:
8e-06
1.001072
2.00221
3.003353
4.004416
...
现在我想从我的虚拟外部数字时钟设备读取时钟使用管道:
def ask_timer(conn):
start=datetime.now()
while True:
now=datetime.now()
delta=now-start
s = delta.seconds + delta.microseconds/1E6
conn.send(s)
parent_conn, child_conn = Pipe()
p = Process(target=ask_timer, args=(child_conn,))
p.start()
while True:
print parent_conn.recv()
time.sleep(1)
它返回:
2.9e-05
6.7e-05
7.7e-05
8.3e-05
8.9e-05
9.4e-05
0.0001
...
这里的定时器似乎不会在后台永久运行,"Queue"的实现如下:
def ask_timer(q):
while True:
now=datetime.now()
delta=now-start
s = delta.seconds + delta.microseconds/1E6
q.put(s)
#conn.close()
q = Queue()
p = Process(target=ask_timer, args=(q,))
p.start()
while True:
print q.get()
time.sleep(1)
执行相同的操作。这只是我对python多处理的误解吗?我怎么能从一个正在运行的并行线程实时请求一个值呢?
一切正常。子进程完全独立于主进程执行ask_timer()
函数。在这个函数中没有任何time.sleep()
,所以它只是在无限循环中以10ms的间隔打印或放入队列增量。
主进程每秒钟向子进程请求一次数据并得到它。
这里的问题是你将更多的数据放入管道/队列,而不是从中获取。所以你得到的是旧数据。要测试您可以在循环中打印队列大小(在OS X上不起作用):
def ask_timer(q):
start = datetime.now()
while True:
now = datetime.now()
delta = now - start
s = delta.seconds + delta.microseconds / 1E6
q.put(s)
q = Queue()
p = Process(target=ask_timer, args=(q,))
p.start()
while True:
print q.get()
print q.qsize()
time.sleep(1)
队列大小将增长得非常快。
显然,你可以使用共享内存从子进程读取当前值。
from multiprocessing import Process, Value
from datetime import datetime
import time
from ctypes import c_double
def ask_timer(v):
start = datetime.now()
while True:
now = datetime.now()
delta = now - start
s = delta.seconds + delta.microseconds / 1E6
v.value = s
val = Value(c_double, 0.0)
p = Process(target=ask_timer, args=(val,))
p.start()
while True:
print(val.value)
time.sleep(1)