1

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()
1
  • 1
    You're using processes (Multiprocessing), not threads, and you can't share variables between processes (without a lot of extra machinery). Commented Nov 27, 2012 at 22:19

2 Answers 2

6

You're using multiprocessing, not threading, which isn't helping your situation. If you were using threading.Thread to create the background worker you'd probably be able to get what you needed by simply throwing in a global time_master call within the function that's being controlled by your background operation. Because you're using multiprocessing, not threading, you will likely need to look into the multiprocessing.Queue class for containers that you can use to pass information back and forth between your processes or to synchronize them. You can also create variables that are shared between the processes as well (all of this is covered in the multiprocessing documentation / examples at the Python Homepage

Sign up to request clarification or add additional context in comments.

Comments

2

You can use Shared Memory, as explained here http://docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes. Remember to wait for the process to finish before reading from the shared space.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.