2012-11-27 229 views
0

我想在解釋器中使用原子操作在兩個線程之間共享變量,如此處所述http://effbot.org/zone/thread-synchronization.htm。核心數據類型的一個簡單的賦值(單字節碼操作)應該是線程安全的,因爲python中的GIL是3.3.2。迄今爲止的理論。以下代碼可以在主模式或從模式下運行(-m或-s)。主模式不斷地通過UDP發送數據。從屬模式確實創建了一個線程來讀取udp端口的數據並更新每個接收數據包的變量。在Python中的兩個線程之間共享變量

示例代碼在創建時將共享變量作爲參數傳遞給線程。我也嘗試過使用全局變量或將線程本地存儲傳遞給線程。

結果是一樣的。在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() 
+1

您正在使用進程('Multiprocessing'),而不是線程,並且不能在進程間共享變量(沒有大量額外的機器)。 – Gerrat

回答

5

您使用multiprocessing,不threading,這是沒有幫助你的情況。如果您正在使用threading.Thread創建後臺工作人員,您可以可能只需在由您的後臺操作控制的功能中投入global time_master調用即可獲得所需的內容。由於您使用的是multiprocessing而不是threading,因此您可能需要查看multiprocessing.Queue類的容器,您可以使用它們在進程之間來回傳遞信息或同步它們。您還可以創建過程以及之間共享(所有這一切都被覆蓋multiprocessing文檔中的變量/在例子Python Homepage

相關問題