I want to share a variable between two threads using atomic operations in the interpreter, as described here http://effbot.org/zone/thread-synchronization.htm. A simple assignment (single bytecode operation) of a core data type should be thread safe, beacuse of the GIL in python < 3.2. So far the theory. The follwing code can be run in either master or slave mode (-m or -s). The master mode does constantly send data via UDP. The slave mode does create a thread to read data from a udp port and update a variable on each received packet.
The example code does pass the shared variable as an argument to the thread on creation. I've tried also by using a global variable or passing a thread local store to the thread.
The result is alwas the same. Inside the read_time_master thread the variable gets assigned. But in the main thread, the value of shared variable isn't updated.
#!/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()
Multiprocessing), not threads, and you can't share variables between processes (without a lot of extra machinery).