244

I have a script and I want one function to run at the same time as the other.

The example code I have looked at:

import threading

def MyThread (threading.thread):
    # doing something........

def MyThread2 (threading.thread):
    # doing something........

MyThread().start()
MyThread2().start()

I am having trouble getting this working. I would prefer to get this going using a threaded function rather than a class.

This is the working script:

from threading import Thread

class myClass():

    def help(self):
        os.system('./ssh.py')

    def nope(self):
        a = [1,2,3,4,5,6,67,78]
        for i in a:
            print i
            sleep(1)


if __name__ == "__main__":
    Yep = myClass()
    thread = Thread(target = Yep.help)
    thread2 = Thread(target = Yep.nope)
    thread.start()
    thread2.start()
    thread.join()
    print 'Finished'
vvvvv
  • 25,404
  • 19
  • 49
  • 81
chrisg
  • 40,337
  • 38
  • 86
  • 107

7 Answers7

410

You don't need to use a subclass of Thread to make this work - take a look at the simple example I'm posting below to see how:

from threading import Thread
from time import sleep

def threaded_function(arg):
    for i in range(arg):
        print("running")
        sleep(1)


if __name__ == "__main__":
    thread = Thread(target = threaded_function, args = (10, ))
    thread.start()
    thread.join()
    print("thread finished...exiting")

Here I show how to use the threading module to create a thread which invokes a normal function as its target. You can see how I can pass whatever arguments I need to it in the thread constructor.

phoenix
  • 7,988
  • 6
  • 39
  • 45
jkp
  • 78,960
  • 28
  • 103
  • 104
  • I have tried this. I have added script up above. Could you tell me how to get the second function running alongside the first one. Thanks – chrisg May 25 '10 at 15:35
  • 10
    @chrissygormley: join() blocks until the first thread finishes. – FogleBird May 25 '10 at 15:40
  • 5
    @chrissygormley: as mentioned, join blocks until the thread you are joining finishes, so in your case, start a second thread with your second function as a target to run the two functions side-by-side, then optionally join one of them if you just want to wait until they are done. – jkp May 25 '10 at 15:45
  • 69
    I kept reading `exiting` as `exciting`, which I thought was more appropriate anyway. – Chase Roberts Apr 13 '16 at 18:58
51

There are a few problems with your code:

def MyThread ( threading.thread ):
  • You can't subclass with a function; only with a class
  • If you were going to use a subclass you'd want threading.Thread, not threading.thread

If you really want to do this with only functions, you have two options:

With threading:

import threading
def MyThread1():
    pass
def MyThread2():
    pass

t1 = threading.Thread(target=MyThread1, args=[])
t2 = threading.Thread(target=MyThread2, args=[])
t1.start()
t2.start()

With _thread:

import _thread
def MyThread1():
    pass
def MyThread2():
    pass

_thread.start_new_thread(MyThread1, ())
_thread.start_new_thread(MyThread2, ())

Doc for _thread.start_new_thread

Niko Föhr
  • 28,336
  • 10
  • 93
  • 96
Jorenko
  • 2,594
  • 2
  • 21
  • 26
  • 3
    The second argument must be a **tuple** for [`thread.start_new_thread(function, args[, kwargs])`](https://docs.python.org/2/library/thread.html#thread.start_new_thread) – venkatvb Jun 09 '15 at 07:00
22

I tried to add another join(), and it seems worked. Here is code

from threading import Thread
from time import sleep

def function01(arg,name):
    for i in range(arg):
        print(name,'i---->',i,'\n')
        print (name,"arg---->",arg,'\n')
        sleep(1)

def test01():
    thread1 = Thread(target = function01, args = (10,'thread1', ))
    thread1.start()
    thread2 = Thread(target = function01, args = (10,'thread2', ))
    thread2.start()
    thread1.join()
    thread2.join()
    print ("thread finished...exiting")

test01()
WestCoastProjects
  • 58,982
  • 91
  • 316
  • 560
GGG
  • 241
  • 2
  • 5
5

Python 3 has the facility of Launching parallel tasks. This makes our work easier.

It has for thread pooling and Process pooling.

The following gives an insight:

ThreadPoolExecutor Example

import concurrent.futures
import urllib.request

URLS = ['http://www.foxnews.com/',
        'http://www.cnn.com/',
        'http://europe.wsj.com/',
        'http://www.bbc.co.uk/',
        'http://some-made-up-domain.com/']

# Retrieve a single page and report the URL and contents
def load_url(url, timeout):
    with urllib.request.urlopen(url, timeout=timeout) as conn:
        return conn.read()

# We can use a with statement to ensure threads are cleaned up promptly
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
    # Start the load operations and mark each future with its URL
    future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}
    for future in concurrent.futures.as_completed(future_to_url):
        url = future_to_url[future]
        try:
            data = future.result()
        except Exception as exc:
            print('%r generated an exception: %s' % (url, exc))
        else:
            print('%r page is %d bytes' % (url, len(data)))

Another Example

import concurrent.futures
import math

PRIMES = [
    112272535095293,
    112582705942171,
    112272535095293,
    115280095190773,
    115797848077099,
    1099726899285419]

def is_prime(n):
    if n % 2 == 0:
        return False

    sqrt_n = int(math.floor(math.sqrt(n)))
    for i in range(3, sqrt_n + 1, 2):
        if n % i == 0:
            return False
    return True

def main():
    with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
        for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
            print('%d is prime: %s' % (number, prime))

if __name__ == '__main__':
    main()
Jeril
  • 7,858
  • 3
  • 52
  • 69
5

the simple way to implement multithread process using threading

code snippet for the same

import threading

#function which takes some time to process 
def say(i):
    time.sleep(1)
    print(i)

threads = []
for i in range(10):
    
    thread = threading.Thread(target=say, args=(i,))

    thread.start()
    threads.append(thread)

#wait for all threads to complete before main program exits 
for thread in threads:
    thread.join()
Nishan B
  • 627
  • 7
  • 11
4

Did you override the run() method? If you overrided __init__, did you make sure to call the base threading.Thread.__init__()?

After starting the two threads, does the main thread continue to do work indefinitely/block/join on the child threads so that main thread execution does not end before the child threads complete their tasks?

And finally, are you getting any unhandled exceptions?

Jeremy Brown
  • 17,880
  • 4
  • 35
  • 28
  • There are no unhandled exceptions and the main thread should run for 30mins. I did not override `__init__`. Is run() required then? Thanks – chrisg May 25 '10 at 15:22
  • I just realized that your example is `def MyThread ( threading.thread )`... I assumed that those were class definitions. If you are going to subclass threading.thread and initialize the thread object with `target=None` or omit the `target` arg, then an implementation of run() is required. Otherwise, if you just want to run a simple task in another thread, see jkp's answer. – Jeremy Brown May 25 '10 at 15:26
4

You can use the target argument in the Thread constructor to directly pass in a function that gets called instead of run.

unholysampler
  • 17,141
  • 7
  • 47
  • 64