well,I wrote a little snappet trying to know how to use python threading .
But strangely the following code just quit quickly without the expected output.
Is it because I shouldn't spawn threads by overiding the run() method?
import threading
from time import sleep
class mythread(threading.Thread):
def __init__(self,target=None,thread_num=5):
threading.Thread.__init__(self,target=None)
self.thn = thread_num
def run(self):
for i in range(self.thn):
t = threading.Thread(target=self.myfunc)
t.start()
t.join()
myfunc(self.thn)
def myfunc(num):
print num,'\tI am doing sth.'
sleep(0.5)
print num,'\tI have done it.'
mythread()
You need to start the thread to make it actually do something:
t = mythread()
t.start()
If you bother to accept a target parameter in your constructor (why?), you shouldn't ignore this parameter. Maybe you want to pass it on to the Thread constructor. (Why?)
When you write mythread(), you instantiate the object. THe default constructor will be called, so __init__() will be executed.
You constructor doesn't have the any instruction of starting the thread.
Related
So I'm new to Python and I'm learning about multi threading. I watched a video on how to do it and followed. I got this:
from threading import *
from time import sleep
class Hello(Thread):
def run(self):
for i in range(5):
print("Hello")
sleep(1)
class Hi(Thread):
def run(self):
for i in range(5):
print("Hi")
sleep(1)
t1 = Hello()
t2 = Hi()
t1.start()
sleep(0.2)
t2.start()
Which prints Hello and Hi simultaneously. But I'm confused about the start used in t1.start() and t2.start() because the classes Hello and Hi don't have a start method. What if I have different methods with different names, how can I call them?
Thank you in advance!
Couple of points:
(1) A Hello instance is a Thread instance. You wrote, class Hello(Thread): .... That declares your Hello class to be a specialization of the Thread class. Your Hello object has a start() method because the Thread class has a start() method.
(2) A Thread instance is not a thread. A thread is an operating system object. A Thread instance is a "handle" that your program uses to create and interact with an operating system thread. The t1.start() call is where the new thread gets created.
(3) After a new thread is created by t1.start(), it will call t1.run(). That's carved in stone. You can't change it, BUT...
(4) ...You write the run() method yourself. It will do whatever you make it do. If you want the thread to call some self.foobar() method, then all you have to do is put a call to self.foobar() inside your run() method.
I have a simple thread that looks (simplified) like this:
import threading
import time
def print_coordinates():
return
listener = threading.Thread(name = "listener", target = print_coordinates)
while(1):
listener.start()
time.sleep(1)
listener.start()
time.sleep(1)
Now, I receive the error RuntimeError: threads can only be started once. As far as I understood, return should cause the thread to "silently exit", as mentioned here. What am I doing wrong?
I think you cannot call start more than once.
See here:
http://docs.python.org/2/library/threading.html#threading.Thread.start
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.
To call it once more, you will have to create another instance of that thread.
My program currently looks something like this:
from threading import Thread
import time
def something():
time.sleep(10)
def function1():
if condition1:
Thread(target=something).start()
def function2():
if condition2:
Thread(target=something).start()
def function3():
if condition3:
Thread(target=something).start()
def main():
Thread(target=function1).start()
Thread(target=function2).start()
Thread(target=function3).start()
main()
If function 1 has already spawned a thread calling something() ,I dont want functions 2 and 3 to spawn another thread calling something().
Actually the code just creates three independent threads and each of these threads then can create another thread doing something, but again completely independent of each other (so getting 3 soemthing threads at max).
Now you ask that these threads interact in a certain manner: "something" should be executed just once. Hence thread "something" must be instantiated only one time and the call must be secured with a lock. Function threads must know about that "something" thread, so you need to create "something" thread in main() and pass it to the function threads.
All in all I am not sure that this will give a simple program structure and it might be good to revise what you want to achieve.
Try following pseudo-code:
import threading
import time
lock = threading.Lock()
def something():
time.sleep(10)
def function1():
if condition1 and lock.acquire(timeout=5):
threading.Thread(target=something).start()
def function2():
if condition2 and lock.acquire(timeout=5):
threading.Thread(target=something).start()
def function3():
if condition3 and lock.acquire(timeout=5):
threading.Thread(target=something).start()
def main():
threading.Thread(target=function1).start()
threading.Thread(target=function2).start()
threading.Thread(target=function3).start()
main()
I've been mucking around with python for a little while and I have recently come up with something involving multithreading... without further ado... heres what I have...
import pythoncom
import wmi
import threading
class Info(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
pythoncom.CoInitialize()
c = wmi.WMI()
detect = c.Win32_ComputerShutdownEvent.watch_for()
detect()
return
if __name__ == '__main__':
Info().start()
for process in c.Win32_Process(Name="something.exe"):
result = process.Terminate()
So my question is... Why does this work? It may be an overall question regarding the process of the inheritence of threading.Thread... but there is no start() def in the class Info() so why does the run def begin?
This is actually a pretty handy application I needed to use to stop an application that always seems to hang when windows shuts down... finding when the windows shutdown event happens was a bit of a headache but luckily tim golden's masterpiece saves the day!
Because it's defined in the parent. Parent classes are checked for attributes if they're not found (or handled) in the child class.
Subclasses of Thread automatically call their run(), when you call start() on them. Start is defined in Thread.
From the docs
There are two ways to specify the activity: by passing a callable object to the constructor, or by overriding the run() method in a subclass.
and from docs on start()
It arranges for the object’s run() method to be invoked in a separate thread of control.
Don't you intent to wait the thread has ended before killing process ?
If so:
if __name__ == '__main__':
info = Info()
info.start()
info.join()
for process in c.Win32_Process(Name="something.exe"):
result = process.Terminate()
obj = functioning()
from threading import Thread
Thread(target=obj.runCron(cronDetails)).start()
print "new thread started..."
I am runnning this, this should run as new thread for runCron function and should print new thread started. but this is not printing new thread started and not creating new thread
You question is missing some details, e.g. what error message you are getting, etc. – below is a working example mimicked after your code.
#!/usr/bin/env python
import time
class Obj(object):
def runCron(self, cronDetails):
time.sleep(1)
print cronDetails
obj = Obj()
cronDetails = "I'm here."
from threading import Thread
# Note, that the `target` is a function object
# (or a callable in general), we don't actually call it yet!
t = Thread(target=obj.runCron, args=(cronDetails, ))
t.start()
print "New thread started (should be here in a second) ..."
It prints:
New thread started (should be here in a second) ...
I'm here.
Looks like you want to call obj.runCron(cronDetails) inside the thread. But what that code does is to call obj.runCron(cronDetails) first, and then pass the result of that to the Thread class.
If that's the case, the code below should fix it:
obj = functioning()
from threading import Thread
Thread(target=obj.runCron, args=(cronDetails,)).start()
print "new thread started..."
Note that I'm not calling obj.runCron myself anymore, but passing that method with the arguments separately to threading.Thread so it can be called inside the thread with the correct arguments.
If that doesn't do what you want, please provide more info as I asked in the comment.