No threading.start_new_thread(), useful addition?

  • Thread starter Ulrich Eckhardt
  • Start date
U

Ulrich Eckhardt

Hi!

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
 
L

Laszlo Nagy

Ulrich Eckhardt írta:
Hi!

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
What is wrong with thread.start_new_thread ? 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. This is quite special, not general enough to make
the suggested change. You can use this one-liner:

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
 
S

sturlamolden

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.
 
U

Ulrich Eckhardt

sturlamolden said:
One usually want to subclass threading.Thread instead of specifying a
target 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!

Uli
 
U

Ulrich Eckhardt

Laszlo said:
Ulrich Eckhardt írta:
What is wrong with thread.start_new_thread ?

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.

Uli
 
H

Hendrik van Rooyen

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().

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
 
L

Laszlo Nagy

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 think you are right! Especially that you can (and probably will) call
other methods from your thread. For example, functions from the standard
library. Or use methods of objects that where created in a different
thread. I think we can say, you must call methods of other (not Thread)
objects if you ever want to do something useful in your thread.

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
 
C

Carl Banks

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 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
 
E

Ethan Furman

Christian said:
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~
 
C

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.

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,183
Messages
2,570,967
Members
47,516
Latest member
ChrisHibbs

Latest Threads

Top