I'm looking at the 'threading' module and see that other than the 'thread'
module it doesn't have a simple function to start a new thread. Instead,
you first have to instantiate a threading object and then start the new
thread on it:
t = threading.Thread(target=my_function)
t.start()
What I'm wondering is if following function wouldn't be a good addition to
the threading module:
def start_new_thread(target, ..):
t = Thread(target, ..)
t.start()
return t
Note: I left out the additional parameters for brevity, but they should of
course be forwarded, but the 'target' parameter is not optional as it is
with Thread's constructor.
Uli
--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
import threading.Thread as thr
thr(target=my_function).start()
But really thread.start_new_thread is better:
import thread.start_new_thread as thr
thr(my_function,arg1,arg2)
Best,
Laci
> I'm looking at the 'threading' module and see that other than the 'thread'
> module it doesn't have a simple function to start a new thread. Instead,
> you first have to instantiate a threading object and then start the new
> thread on it:
>
> t = threading.Thread(target=my_function)
> t.start()
One usually want to subclass threading.Thread instead of specifying a
target function.
class mythread(threading.Thread):
def run():
# whatever
pass
t = mythread()
t.start()
Also, you may want to set the daemon flag before starting the thread,
which is why the thread is created in a suspended state.
Please don't use the thread module directly, especially the
start_new_thread function. It a low level function that bypasses the
threading framework. The is no good reason to use this function in favor
of threading.Thread().
Christian
The 'thread' module is more or less deprecated.
> At least it supports function arguments. Your suggested addition would
> only useful if you want to start argument-less functions in separate
> threads, from multiple places in a module.
To quote from my own posting:
| Note: I left out the additional parameters for brevity, but they
| should of course be forwarded, but the 'target' parameter is not
| optional as it is with Thread's constructor.
No, this is supposed to support function arguments, too.
> You can use this one-liner:
>
> import threading.Thread as thr
>
> thr(target=my_function).start()
No, as this one doesn't give me a handle to the thread. I also find this
barely readable, for sure it doesn't beat the readability of the proposed
function.
No. You also don't derive from a file class in order to read a file. The
point is that the Thread instance is not a thread but it is an object that
can be used to access a thread, similar to a File instance which file which
is not the file but just an object to access one.
I personally find it much cleaner this way. Also, why should any code care
in which thread it is executed? Why should I have to derive a class from
some other only because I want to run one of its functions in a separate
thread?
I don't want to start a discussion which principle is better, that would
only end in endless discussions, but I'd like to point out that the
principle of deriving from a thread class is not universally accepted. ;)
Cheers!
I have seen this advice a couple of times now, and I do not understand it.
From my perspective (which is admittedly jaundiced) Threading just adds a
bunch of superfluous stuff like a run method and other weird things that I
cannot see a need for.
The simplicity of this kind of code:
def this_is_a_thread(arg1,arg2):
do_some_initialisation(arg1,arg2)
while some_condition:
do_some_stuff()
which then gets started with thread.start_new_thread, does it for me.
What does the Threading module buy me, other than a formal OO approach?
- Hendrik
* the interpreter won't know about your thread when you bypass the
threading module and use the thread module directly. The thread isn't in
the list of active threads and the interpreter is unable to wait for the
thread to exit when Python shuts down. All threads created by the thread
module behave like daemonic threads.
* exception reporting doesn't work with thread.start_new_thread
* profiling and tracing doesn't work with thread.start_new_thread
* introspection of active thread doesn't work because threads started by
thread.start_new_thread are invisible for the rest of the interpreter
* you have to roll your own system to join a thread
* probably more stuff
In Python 3.0 the thread module has been renamed to _thread in order to
reflect the nature of the C extension.
Christian
Roll your own convenient function, though. :) At work we have this short
function in our tool box:
def daemonthread(target, name=None, autostart=True, args=(), kwargs=None):
"""Start a thread as daemonic thread
"""
thread = Thread(target=target, name=name, args=args, kwargs=kwargs)
thread.setDaemon(True)
if autostart:
thread.start()
return thread
Christian
Now I'm beginnig to agree with you, Ulrich. We have
threading.enumerate() - it can be used to list active threads. So if you
only want to start a function in a separate thread, then you do not
really need the Thread object. Then we do you HAVE TO create a Thread
object explicitely?
Of course you can easily create a nice decorator like this:
import threading
def threadlaunch(func):
def launcher(*args,**kwargs):
thr = threading.Thread(target=func,args=args,kwargs=kwargs)
thr.start()
return thr
return launcher
And then do something like:
import time
@threadlaunch
def print_something(w,s):
print "please wait..."
time.sleep(w)
print s
thr = print_something(3,"Test")
print "started print_something in",thr
How about that? (Or was it your concern that it is not part of the
standard library?)
Best,
Laszlo
I have to agree. I've been trying to understand some other entity's
Java code lately, and it's mondo-confusing because there is a subclass
of Thread that has methods that are called from other threads. To
make matters worse the variable this method is assigned to is called,
simply, "thread".
As far as I can discern doing that way (as opposed to using a Runnable
object) didn't have any effect except to make the logic harder to
understand.
So (getting back to Python) count me among those who say one usally
want to specify a target function instead of subclassing
threading.Thread.
Carl Banks
You are entitled to your opinion but I STRONGLY recommend against your
decorator. You MUST NOT start threads a a side effect of a module
import. It can lead to severe bugs and dead lock the entire interpreter.
I'm speaking as an experienced Python developer and a CPython core
developer. Please trust me in this. The interaction between the import
system, its global import lock and threads can and will lead to
surprising and hard to debug bugs. A well designed application loads its
modules first and then initializes its components explicitly. You don't
want to fire up threads randomly!
Christian
Okay, I for one will never start threads as a side-effect of module import.
Other than that, are there other inherent problems with using that
decorator at non-import times?
~Ethan~
L
His decorator doesn't do that (necesarily).
His example code did that, but I took it to be an example script, and
it's kind of hard to run code that's not a side effect of importing
__main__.
Carl Banks