Search code examples
pythonmultiprocessingpython-multiprocessing

How can shared variables be implemented in a python class using multiprocessing?


The program has two main functions which are running while True loops. The clickSpot function waits till signal_found is True and then clicks self.spot, a location on the screen, then increments self.actions_done by 1. self.spot is changed by getInputFromUser, while also displaying self.actions_done, which is changed by clickSpot.

Here's an example of the code I'm running:

import multiprocessing

class Program():
    def __init__(self):
        self.spot = (0,0)
        self.do_action = False
        self.actions_done = 0
      
        second_process = multiprocessing.Process(target=self.clickSpot)
        getInputFromUser()


    def getInputFromUser(self):
        while True:        
            self.spot = ...input changed by user
            ...displays self.actions_done
            ...input from user that toggles self.exit
    

    def clickSpot(self):
        while True:
            signal_found = check_signal() ...returns True or False 
            if signal_found == True:
                click(self.spot)
                self.actions_done += 1
                signal_found = False
            
       
    def exit(self):
        ...closes GUI in getInputFromUser and stops clickSpot process

My current implementation involves multithreading. However, both threads slow down when the GUI is being interacted with. I have not managed to get this to work with multiprocessing .

The expected result is to have getInputFromUser and clickSpot run simultaneously and share self.spot and self.actions_done.


Solution

  • your problem seems like something you should be doing "correctly" using multithreading and Event Objects and conditon objects

    while True:
        signal_found = check_signal()
        if signal_found == True:
    

    is a busy wait, which WILL make your app slower using threads or burn a hole through your CPU if you ported this to multiprocessing, it should be replaced with a threading.condition.

    condition_obj1 = threading.Condition()
    condition_obj2 = threading.Condition()
    
    def clickSpot(self):
        while True:
            condition_obj1.wait()  # .notify() instead of setting signal_found=True
            click(self.spot)
            self.actions_done += 1
    
    def getInputFromUser(self):
        while True:
            condition_obj2.wait()  # notified inside a GUI event that listens on user input
            self.spot = ...input changed by user
            ...displays self.actions_done
            ...input from user that toggles self.exit
    

    this doesn't answer the original question which is how to share a variable through multiprocessing.

    well, there are multiprocessing versions of condition and event and there are multiprocessing.Value and multiprocessing.Queue for sharing values between processes, which allow sharing values, but this is not what you currently need.