我想在解释器中使用原子操作在两个线程之间共享一个变量,如http://effbot.org/zone/thread-synchronization.htm所述。核心数据类型的简单赋值(单字节码操作)应该是线程安全的,因为python中的GIL< 3.2。到目前为止理论。以下代码可以在主模式或从模式下运行(-m或-s)。主模式通过UDP不断发送数据。从模式确实创建了一个线程来从udp端口读取数据并更新每个接收到的数据包的变量。
示例代码确实将共享变量作为参数传递给创建时的线程。我也试过使用全局变量或将线程本地存储传递给线程。
结果是一样的。在read_time_master线程内部,变量被赋值。但是在主线程中,共享变量的值不会更新。
#!/usr/bin/env python
import socket
import itertools
import multiprocessing
from optparse import OptionParser
from time import sleep
PORT = 1666
def read_time_master(sock, time_master):
while True:
time_master = float(sock.recvfrom(1024)[0])
def main():
time_master = 0.0
p = OptionParser()
p.add_option('--master', '-m', action='store_true')
p.add_option('--slave', '-s', action='store_true')
options, arguments = p.parse_args()
if options.master or options.slave:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
if options.master:
sock.connect(('127.0.0.1', PORT))
if options.slave:
sock.bind(('0.0.0.0', PORT))
recv_thread = multiprocessing.Process(target=read_time_master, args=(sock, time_master))
recv_thread.start()
for time in itertools.count():
print time
if options.slave:
print "master: %f" % time_master # -> not updated from other thread
if options.master:
try:
sock.send(str(time))
except socket.error:
pass
sleep(1)
if options.master or options.slave:
sock.close()
if __name__ == '__main__':
main()
答案 0 :(得分:5)
您使用的是multiprocessing
,而不是threading
,这对您的情况没有帮助。如果您使用threading.Thread
创建后台工作程序,那么可能能够通过在被受控制的函数中调用global time_master
调用来获得所需内容你的后台操作。由于您使用的是multiprocessing
,而不是threading
,因此您可能需要查看multiprocessing.Queue
类,以了解可用于在流程之间来回传递信息或同步的容器他们。您也可以创建在流程之间共享的变量(所有这些都在Python Homepage
multiprocessing
文档/示例中介绍
答案 1 :(得分:1)
您可以使用共享内存,如http://docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes所述。请记住在从共享空间读取之前等待该过程完成。