Creazione di thread in Python


177

Ho uno script e voglio che una funzione sia eseguita contemporaneamente all'altra.

Il codice di esempio che ho visto:

import threading

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

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

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

Ho problemi a farlo funzionare. Preferirei farlo usando una funzione threaded piuttosto che una classe.

Questo è lo script funzionante:

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'

Risposte:


323

Non è necessario utilizzare una sottoclasse di Threadper farlo funzionare: dai un'occhiata al semplice esempio che sto postando di seguito per vedere come:

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")

Qui mostro come usare il modulo threading per creare un thread che invoca una normale funzione come target. Puoi vedere come posso passare qualsiasi argomento di cui abbia bisogno nel costruttore del thread.


Ci ho provato Ho aggiunto lo script sopra. Potresti dirmi come far funzionare la seconda funzione insieme alla prima. Grazie
chrissygormley,

6
@chrissygormley: join () blocchi fino al termine del primo thread.
FogleBird,

4
@chrissygormley: come accennato, unisci i blocchi fino al termine del thread a cui stai unendo, quindi, nel tuo caso, avvia un secondo thread con la tua seconda funzione come destinazione per eseguire le due funzioni fianco a fianco, quindi uniscile facoltativamente a una di esse se vuoi solo aspettare fino a quando non hanno finito.
jkp,

41
Continuavo a leggere exitingcome exciting, che pensavo fosse più appropriato comunque.
Chase Roberts,

42

Ci sono alcuni problemi con il tuo codice:

def MyThread ( threading.thread ):
  • Non è possibile eseguire la sottoclasse con una funzione; solo con una classe
  • Se avessi intenzione di utilizzare una sottoclasse, ti consigliamo di eseguire il threading: filetto, non threading

Se vuoi davvero farlo con solo le funzioni, hai due opzioni:

Con filettatura:

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

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

Con filo:

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

thread.start_new_thread(MyThread1, ())
thread.start_new_thread(MyThread2, ())

Doc per thread.start_new_thread


2
Il secondo argomento deve essere una tupla perthread.start_new_thread(function, args[, kwargs])
venkatvb,

13

Ho provato ad aggiungere un altro join () e sembra funzionare. Ecco il codice

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

3

È possibile utilizzare l' targetargomento nel Threadcostruttore per passare direttamente a una funzione che viene chiamata anziché run.


2

Hai ignorato il metodo run ()? Se hai ignorato __init__, ti sei assicurato di chiamare la base threading.Thread.__init__()?

Dopo aver avviato i due thread, il thread principale continua a funzionare indefinitamente / bloccare / unire i thread figlio in modo che l'esecuzione del thread principale non termini prima che i thread figlio completino le loro attività?

E infine, ricevi eccezioni non gestite?


Non ci sono eccezioni non gestite e il thread principale dovrebbe essere eseguito per 30 minuti. Non ho ignorato __init__. Run () è richiesto allora? Grazie
chrissygormley,

Mi sono appena reso conto che il tuo esempio è def MyThread ( threading.thread )... Ho pensato che quelle fossero definizioni di classe. Se si intende eseguire la sottoclasse di threading.thread e inizializzare l'oggetto thread con target=Noneo omettere l' targetarg, è necessaria un'implementazione di run (). Altrimenti, se vuoi semplicemente eseguire una semplice attività in un altro thread, vedi la risposta di jkp.
Jeremy Brown,

0

Python 3 ha la possibilità di avviare attività parallele . Questo semplifica il nostro lavoro.

Ha per il pool di thread e il pool di processi .

Di seguito viene fornita una panoramica:

Esempio ThreadPoolExecutor

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

Un altro esempio

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()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.