views:

103

answers:

4

I have two definitions or methods in python. I'd like to run them at the same exact time. Originally I tried to use forking but since the child retained the memory from the parent, it's writing multiple things that I don't need in a file. So I switched to threading.

I have something similar to

import threading
class test(threading.Thread)
     def __init__(self,numA, list):
          self.__numA=numA #  (random number)
          self.__list=list  #(list)
     def run(self):
          makelist(self)
          makelist2(self)

makelist() and makelist2() use numA and list. So in those definitions/methods instead of saying

print list 

I say

print self.__list.

In the main() I made a new class object:

x = test()
x.start()

When I run my program I get an attribute error saying it cannot recognize the __list or __numA.

I've been stuck on this for a while. If there's another better way to run two methods at the same time (the methods are not connected at all) please inform me of so and explain how.

Thank you.

A: 

A Couple of things:

A) When you override the _init_ method of the threading.Thread object you need to initialize threading.Thread yourself which can be accomplished by putting "threading.Thread._init_(self)" at the end of the _init_ function

B) As msw pointed out those calls to "makelist" and "makelist2" seem to be to global functions which kinda defeats the purpose of the threading. I recommend making them functions of test.

Joshkunz
+1  A: 

The __list and __numA won't be visible from makelist and makelist2 if they are not also members of the same class. The double underscore will make things like this fail:

>>> class A(object):
...    def __init__(self):
...        self.__a = 2
...
>>> def f(x):
...    print x.__a
...
>>> a = A()
>>> f(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in f
AttributeError: 'A' object has no attribute '__a'

But, naming the __a something without two leading underscores would work. Is that what you are seeing?

You can read more about private variables in the python documentation.

Mattias Nilsson
+1  A: 

Firstly, don't name your variable the same as built-in types or functions, i.e. list.

Secondly. as well as the problems that others have pointed out (__ name mangling, initialising Thread etc), if your intention is to run makelist and makelist2 at the same time then you are doing it wrong, since your run method will still execute them one after the other. You need to run them in separate threads, not sequentially in the same thread.

Thirdly how exact do you mean by "same exact time"? Using threads in (C)Python this is physically impossible, since the execution will be interleaved at the bytecode level. Other versions of Python (Jython, IronPython etc) may run them at exactly the same time on a multi-core system, but even then you have no control over when the OS scheduler will start each one.

Finally it is a bad idea to share mutable objects between threads, since if both threads change the data at the same time then unpredictable things can (and will) happen. You need to protect against this by either using locks or only passing round immutable data or copies of the data. Using locks can also cause its own problems if you are not careful, such as deadlocks.

Dave Kirby
Thank you so much! I made separate threads and it worked.
ykmizu
+1  A: 

I'd like to run them at the same exact time.

You can't do this with threading: the Global Interpreter Lock in Python ensures that only one thread can execute Python code at any time (threads are switched every sys.getcheckinterval() bytecodes). Use multiprocessing instead:

from multiprocessing import Process
import os

def info(title):
    print title
    print 'module name:', __name__
    print 'parent process:', os.getppid()
    print 'process id:', os.getpid()

def f(name):
    info('function f')
    print 'hello', name

if __name__ == '__main__':
    info('main line')
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()
katrielalex