1

I have a script using threaded timers that manipulates 2 common lists at random.

Because the class instances manipulate the lists on threaded timers, I cannot pass the variables to the classes & back.

…All instances of the classes need to manipulate a single, up to date list.

Because of that, the scope of those lists are set to global. However, I need the scope to be at the class level, yet be manipulated by multiple classes.

To clarify...

Here's the basic program structure:

Global list variable_1
Global list variable_2

class MasterClass:
    # this creates instances of the threaded classes. 
    There are 50+ instances of MasterClass creating thousands
    of instances of ThreadedClass1, 2, & 3.  All manipulate
    global list variables 1 & 2.

class ThreadedClass1:
    # threaded classes manipulate global list variables 1 & 2 on random timers.

class ThreadedClass2:

class ThreadedClass3:

The problem: For each instance of MasterClass I need a separate list variable 1 & 2. Each instance of ThreadedClasses called by that instance of MasterClass must manipulate only the list variables owned by that instance of MasterClass.

Basically I need the equivalent of a global list variable, but I need it to be encapsulated by an instance of MasterClass, and be manipulated by any instance of ThreadedClasses called by that instance of MasterClass only.

How's this done?

Excelsior
  • 121
  • 2
  • 9

2 Answers2

1

Try to pass instance of MasterClass to every produced instance of ThreadedClasses.

Then, define thread save methods in MasterClass, that will perform manipulation with your variable_1, variable_2. ThreadedClasses shall not touch this lists directly, only by calling those methods.

Small example (check subclassing from object):

import threading


class ThreadedClassBase(object):
    def __init__(self, master, *args, **kwargs):
        self.master = master

    def do_something(self):
        self.master.append(1, 'some_value')
        value = self.master.getitem(1, 0)


class ThreadedClass1(ThreadedClassBase):
    def __init__(self, *args, **kwargs):
        super(ThreadedClass1, self).__init__(*args, **kwargs)
        # ...

# same for ThreadedClass2, 3


class MasterClass(object):
    def __init__(self, *args, **kwargs):
        self.variable_1 = list()
        self.variable_2 = list()
        self.lock = threading.Lock()
        for i in range(50):
            ThreadedClass1(master=self)
            # create new thread

    def append(list_nb, value):
        with self.lock:
            getattr('variable_' + list_nb).append(value)

    def getitem(list_nb, index):
        with self.lock:
            return getattr('variable_' + list_nb)[index]
Community
  • 1
  • 1
stalk
  • 11,934
  • 4
  • 36
  • 58
0

If I understand correctly, you should be able to make them instance variables of MasterClass and pass them into the constructors.

eg.

class MasterClass:
    def __init__(self):
        self.variable_1 = [...]
        self.variable_2 = [...]
        self.tc1 = ThreadedClass1(self.variable_1, self.variable_2)
        self.tc2 = ThreadedClass2(self.variable_1, self.variable_2)
        self.tc3 = ThreadedClass3(self.variable_1, self.variable_2)

Alternatively pass the whole instance in

class MasterClass:
    def __init__(self):
        self.variable_1 = [...]
        self.variable_2 = [...]
        self.tc1 = ThreadedClass1(self)
        self.tc2 = ThreadedClass2(self)
        self.tc3 = ThreadedClass3(self)

class ThreadedClass1:
    def __init__(self, parent):
        self.mc = parent

etc.

John La Rooy
  • 295,403
  • 53
  • 369
  • 502
  • Variable_1 & 2 are manipulated by thousands of instances of the threaded classes all on random timers. If I pass the variables this way, how do I keep them in sync? Meaning an instance of Threadedclass changes the variables then returns the changed variable to MasterClass, but in the interim several other instances of Threadedclass have changed that variable as well. Somehow I need to structure the code so that all instances of reference & change the same variables. – Excelsior Oct 15 '14 at 21:15
  • The variables aren't "returned" - they are references to _the same_ list. – John La Rooy Oct 15 '14 at 22:13
  • Thanks gnibbler… but I think I'm missing something here… …They references the same list. But what about when changes are made to the lists by ThreadedClass? self.tc1 = ThreadedClass1(self.variable_1, self.variable_2) As far as I understand the scope of variable_1 & 2 would then be at the ThreadedClass level? Any changes to them would only be changed within the scope of that instance of ThreadedClass1 & not changed within the scope of MasterClass? Or am I missing something? – Excelsior Oct 16 '14 at 01:13
  • You're misunderstanding how references work. You end up with say 4 variables/names/references with their own respective scopes, but they are all references to the same list. The list object itself doesn't have a scope - it's just an object. – John La Rooy Oct 16 '14 at 01:19
  • Sorry. I'm not getting this… To rundown… Each Instance of MasterClass creates the list objects. MasterClass creates an instance of ThreadedClass with: self.tc1 = ThreadedClass1(self.variable_1, self.variable_2) Now ThreadedClass holds those variables. We now have 4 variables. 2 at the scope of MasterClass & 2 at the scope of ThreadedClass. ThreadedClass makes changes to those variables. How would I get those changes to instantly reflect in the values of those variables at the MasterClass scope? – Excelsior Oct 16 '14 at 01:41