1

I'm stuck with a threading problem here. I need threads to access a global variable.

I've read a previous answer to a similar question and I understood the "power" of the global keyword in order for functions and threads to access to global variables.

I'm able to make the following code work and it is pretty straightforward to me:

# WORKING CODE !!!

from threading import Thread
import sys, time

a = "" #global variable

def thread1(threadname):
    global a
    while True:
        a *= 2
        time.sleep(2)

def thread2(threadname):
    global a
    while True:
        a += 1
        time.sleep(1)

if __name__ == "__main__":
    thread1 = Thread( target=thread1, args=("Thread-1", ) )
    thread2 = Thread( target=thread2, args=("Thread-2", ) )

    a = 23

    thread1.start()
    thread2.start()

    while True:
        print(a)

Now I would like to have an OSC driven function to modify the global variable a. I'm using the python-osc module and I'm making the OSC server running on its own thread. As before I have declared a as a global variable inside the mapped function associated with the "/learn" OSC method.

Strangely to my comprehension the following code is not behaving the same way as the previous one.

edited 2018-10-18, 16:14: "a" is not increasing at all and what I'm seeing printed is

a: 1

printed continuosly. As if we had two different "a" values: one that is increasing inside the OSC thread which is different from the global "a" of the main one.

What I doing wrong?

import threading
from time import sleep
from pythonosc import osc_server, dispatcher

OSCaddress = "192.168.1.68"
OSCport    = 13000

a = ""

# OSC functions
def menageLearnButton(unused_addr, args, value):
    global a
    if value == 1:
        a += 1
    else:
        a += 3

if __name__ == "__main__":
    # OSC dispatcher to respond to incoming OSC messages
    dispatcher = dispatcher.Dispatcher()
    dispatcher.map("/learn", menageLearnButton, "learning")

    a = 1

    # better to run the OSC server on its own thread
    # in order not to block the program here
    OSCserver = osc_server.ForkingOSCUDPServer((OSCaddress, OSCport), dispatcher)
    OSCserver_thread = threading.Thread(target=OSCserver.serve_forever)
    OSCserver_thread.start()

    while True:
        print("a: {}".format(a))
        sleep(1)

Thank you very much for your support.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
orestino
  • 113
  • 1
  • 1
  • 8
  • Are you sure `value` does have the value that you expect? – astorga Oct 18 '18 at 13:10
  • Hi @astorga, yes. On some previous tests I've made i've placed a print inside the `menageLearnButton` to make this exact same check. However, here there's also an `else` statement which should increment the `a` variable regardless of the value of the `value`. – orestino Oct 18 '18 at 14:21

1 Answers1

3

I think what is going on is that 'ForkingOSCUDPServer' is creating a new process for each OSC request so 'a' is getting reinitialized each time. If I switch your code to use 'ThreadingOSCUDPServer' it seems to have the desired behavior.

RawBengal
  • 46
  • 2
  • Thank you @RawBengal, you are right! Thank you for your precious support and excuse me form my late reply :) – orestino Dec 08 '18 at 18:26
  • Thank you both for your great question and answer. Helped me solve the same issue! :) – spal Nov 26 '22 at 20:47