I am using python 2.7 and new to Threading. I got a class file and run method. But I don't see the run method invoked when I create instances of thread. I am also planning to use subprocess.Popen inside the run method and get stdout of the process for each filename and print the output.
Please tell me what I am missing here for run method to be called.
class FileScanThread(threading.Thread):
def __init__(self, myFileName):
print("In File Scan Thread")
self.mapFile = myFileName
#myjar=myFileName
self.start()
def run(self):
print self.mapFile
x= FileScanThread("myfile.txt")
you're forgetting to call the mother class constructor to specify target. It's not java, and run has no particular meaning. By default, target is None and the thread does nothing.
import threading
class FileScanThread(threading.Thread):
def __init__(self, myFileName):
threading.Thread.__init__(self,target=self.run)
# another syntax uses "super", which is simpler in python 3
# super().__init__(target=self.run)
print("In File Scan Thread")
self.mapFile = myFileName
#myjar=myFileName
self.start()
def run(self):
print(self.mapFile)
x= FileScanThread("myfile.txt")
x.join() # when you're done
This will do what you want. You aren't calling __init__ from the class Thread.
class FileScanThread(threading.Thread):
def __init__(self, myFileName):
threading.Thread.__init__(self)
print("In File Scan Thread")
self.mapFile = myFileName
#myjar=myFileName
self.start()
def run(self):
print self.mapFile
x = FileScanThread("myfile.txt")
I don't think you have to pass target argument to it. At least that's not usually how I do it.
Output:
In File Scan Thread
myfile.txt
Related
I have this example code:
# some imports that I'm not including in the question
class daemon:
def start(self):
# do something, I'm not including what this script does to not write useless code to the question
self.run()
def run(self):
"""You should override this method when you subclass Daemon.
It will be called after the process has been daemonized by
start() or restart().
"""
class MyDaemon(daemon):
def run(self):
while True:
time.sleep(1)
if __name__ == "__main__":
daemonz = MyDaemon('/tmp/daemon-example.pid')
daemonz.start()
def firstfunction():
# do something
secondfunction()
def secondfunction():
# do something
thirdfunction()
def thirdfunction():
# do something
# here are some variables set that I am not writing
firstfunction()
How can I exit from the run(self) function of class "daemon" and going on executing the firstfunction() like written in the last line? I'm a newbie with Python, and I'm trying to learn
# EDIT
I managed to implement the daemon class into the treading class. But I'm in the same situation of first, the script stays in daemon class and doesn't execute the other lines.
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def daemonize(self):
# istructions to daemonize my script process
def run(self):
self.daemonize()
def my_function():
print("MyFunction executed") # never executed
thread = MyThread()
thread.start()
my_function() # the process is successfully damonized but
# this function is never executed
You may use the breakkeyword to exit loops, and continue to the next line. return can be used to exit functions.
class daemon:
def start(self):
self.run()
def run(self):
while True:
break
return
print() # This never executes
If you want MyDaemon to run alongside the rest of your code, you have to make it a process or thread. Code then automatically continues to the next line, while the MyDaemon class (thread/process) runs.
import threading
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
print("Thread started")
while True:
pass
def my_function():
print("MyFunction executed")
thread = MyThread()
thread.start() # executes run(self)
my_function()
This code produces the following result:
Thread started
MyFunction executed
To make thread a daemon, you can use thread.setDaemon(True). That function must be called before the thread is started:
thread = MyThread()
thread.setDaemon(True)
thread.start()
my_function()
I'm new to OOP and am trying to figure out how to get the result of something outside of a class in order to decide what to do next in my program.
I'm unzipping a file, and if it takes too long then I want the process to terminate. This code will do just that:
class Command(object):
def __init__(self,cmd):
self.cmd = cmd
self.process = None
def run(self,timeout):
def target():
print("Thread started")
self.process = subprocess.Popen(self.cmd)
self.process.communicate()
print("Thread finished")
thread = threading.Thread(target=target)
thread.start()
thread.join(timeout)
if thread.is_alive():
print("\nTerminating process")
self.process.terminate()
thread.join()
print(self.process.returncode)
def unzip_file(file,dirout,attempt):
just_name = os.path.splitext(file)[0]
print('unzip started at {} for {}'.format(datetime.datetime.now(),file))
command = Command(zip_exe+' x '+file+' -o'+path+dirout)
command.run(timeout = 300)
...but what if I wanted to get the the command output, outside of the function that was called inside the Class? Say to a variable called 'tmp'. I've added two annotated lines to illustrate what I'm trying to do which of course returns an error.
class Command(object):
def __init__(self,cmd):
self.cmd = cmd
self.process = None
def run(self,timeout):
def target():
print("Thread started")
self.process = subprocess.Popen(self.cmd)
self.tmp = self.proc.stdout.read() #get the command line output
self.process.communicate()
print("Thread finished")
thread = threading.Thread(target=target)
thread.start()
thread.join(timeout)
if thread.is_alive():
print("\nTerminating process")
self.process.terminate()
thread.join()
print(self.process.returncode)
def unzip_file(file,dirout,attempt):
just_name = os.path.splitext(file)[0]
print('unzip started at {} for {}'.format(datetime.datetime.now(),file))
command = Command(zip_exe+' x '+file+' -o'+path+dirout)
command.run(timeout = 300)
print(self.tmp) #print the command line output (doesn't work)
This line self.tmp = self.proc.stdout.read() puts some data into a member variable. You can then use it outside of the class by simple using a reference to the object:
...
command.run(timeout = 300)
print(command.tmp)
Your problem seems to be that the identifier self is not defined in function unzip_file. Try replacing
print(self.tmp) #print the command line output (doesn't work)
with
print(command.tmp)
Identifier self has a special meaning when used in the scope of a class and refers to the instance of that class. When used elsewhere (as in unzip_file), the identifier has no special meaning and is just a regular undefined identifier.
Aside from your actual problem, you might want to research communication mechanisms between threads. Queue module is a good place to look at if you already understand the basics. If you are new to the topic, then this one is a decent introduction.
In another class:
self.workerThread = WorkerThread()
def startThread():
self.workerThread.setGameName("pizza")
self.workerThread.start()
QThread class:
class WorkerThread(QThread):
def _init_(self, parent = None):
super(WorkerThread, self)._init_(parent)
self.gameName = ""
def setGameName(self, currGameName):
self.gameName = currGameName
def run(self):
#do something with self.gameName
In main:
startThread()
startThread()
When I run this, it uses the gameName from the first call and not the second. The function calls seem interleaved. Can someone explain how Qthread works? How do i set a gameName for each individual function call of startThread()?
If start() is called twice on a QThread then the second call will do nothing if the thread is still running. It looks like there's a good chance this is what's happening, and if not then it's only due to luck.
I have the following code in python:
class gateWay:
def __init__(self):
self.var1 = []
self.var2 = {}
self.currentThread = None
def stateProcess(self, file):
# some irrelevant code
self.currentThread = saltGatWayThread(self, file).start()
return self.var1
def stopRunning(self):
self.currentThread.proc.stop()
In addition, here the source code of the saltGatWayThread:
class saltGatWayThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
# some irrelevant code
self.proc = src.proc.Process1()
In addition, I have the following code in src/proc/__init__.py:
class Process1:
def stop(self):
# code to stop operation
In the console, I notice that self.currentThread is null.
My purpose is to save the thread in local variable, when start it. If I get an abort request, I apply
stopRunning function. This function, would take the saved thread and will do "clean" exit (finish the process of the tread and exit).
Why can't I save the thread, and use the structure of it later on?
invoke currentThread = saltGatWayThread() and then call .start(). currentThread does not contains thread instance because starts() method always returns nothing according to the threading.py source code. See source of C:\Python27\Lib\threading.py
def start(self):
"""Start the thread's activity.
It must be called at most once per thread object. It arranges for the
object's run() method to be invoked in a separate thread of control.
This method will raise a RuntimeError if called more than once on the
same thread object.
"""
if not self.__initialized:
raise RuntimeError("thread.__init__() not called")
if self.__started.is_set():
raise RuntimeError("threads can only be started once")
if __debug__:
self._note("%s.start(): starting thread", self)
with _active_limbo_lock:
_limbo[self] = self
try:
_start_new_thread(self.__bootstrap, ())
except Exception:
with _active_limbo_lock:
del _limbo[self]
raise
self.__started.wait()
I have a thread class, in it, I want to create a thread function to do its job corrurently with the thread instance. Is it possible, if yes, how ?
run function of thread class is doing a job at every, excatly, x seconds. I want to create a thread function to do a job parallel with the run function.
class Concurrent(threading.Thread):
def __init__(self,consType, consTemp):
# something
def run(self):
# make foo as a thread
def foo (self):
# something
If not, think about below case, is it possible, how ?
class Concurrent(threading.Thread):
def __init__(self,consType, consTemp):
# something
def run(self):
# make foo as a thread
def foo ():
# something
If it is unclear, please tell . I will try to reedit
Just launch another thread. You already know how to create them and start them, so simply write another sublcass of Thread and start() it along the ones you already have.
Change def foo() for a Thread subclass with run() instead of foo().
First of all, I suggest the you will reconsider using threads. In most cases in Python you should use multiprocessing instead.. That is because Python's GIL.
Unless you are using Jython or IronPython..
If I understood you correctly, just open another thread inside the thread you already opened:
import threading
class FooThread(threading.Thread):
def __init__(self, consType, consTemp):
super(FooThread, self).__init__()
self.consType = consType
self.consTemp = consTemp
def run(self):
print 'FooThread - I just started'
# here will be the implementation of the foo function
class Concurrent(threading.Thread):
def __init__(self, consType, consTemp):
super(Concurrent, self).__init__()
self.consType = consType
self.consTemp = consTemp
def run(self):
print 'Concurrent - I just started'
threadFoo = FooThread('consType', 'consTemp')
threadFoo.start()
# do something every X seconds
if __name__ == '__main__':
thread = Concurrent('consType', 'consTemp')
thread.start()
The output of the program will be:
Concurrent - I just startedFooThread - I just started