ここhttp://effbot.org/zone/thread-synchronization.htmで説明されているように、インタープリターでアトミック操作を使用して 2 つのスレッド間で変数を共有したいと考えています。Python 3.2 未満の GIL のため、コア データ型の単純な割り当て (単一のバイトコード操作) はスレッド セーフである必要があります。ここまで理論。次のコードは、マスター モードまたはスレーブ モード (-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()