web-dev-qa-db-fra.com

Création de threads dans python

J'ai un script et je veux qu'une fonction soit exécutée en même temps que l'autre.

L'exemple de code que j'ai consulté:

import threading

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

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

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

J'ai du mal à obtenir que cela fonctionne. Je préférerais que cela fonctionne en utilisant une fonction threadée plutôt qu'une classe.

C'est le script de travail:

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 __== "__main__":
    Yep = myClass()
    thread = Thread(target = Yep.help)
    thread2 = Thread(target = Yep.nope)
    thread.start()
    thread2.start()
    thread.join()
    print 'Finished'
151
chrissygormley

Vous n'avez pas besoin d'utiliser une sous-classe de Thread pour que cela fonctionne. Jetez un coup d'œil à l'exemple simple que je présente ci-dessous pour voir comment:

from threading import Thread
from time import sleep

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


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

Ici, je montre comment utiliser le module de threading pour créer un thread qui appelle une fonction normale en tant que cible. Vous pouvez voir comment je peux passer tous les arguments dont j'ai besoin dans le constructeur du thread.

287
jkp

Il y a quelques problèmes avec votre code:

def MyThread ( threading.thread ):
  • Vous ne pouvez pas sous-classe avec une fonction; seulement avec une classe
  • Si vous alliez utiliser une sous-classe, vous voudriez threading.Thread, pas threading.thread

Si vous voulez vraiment faire cela avec seulement des fonctions, vous avez deux options:

Avec filetage:

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

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

Avec fil:

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

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

Doc pour thread.start_new_thread

38
Jorenko

J'ai essayé d'ajouter un autre join (), et cela semble fonctionné. Voici le 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()
11
GGG

Vous pouvez utiliser l'argument target du constructeur Thread pour transmettre directement une fonction appelée à la place de run.

3
unholysampler

Avez-vous remplacé la méthode run ()? Si vous avez remplacé __init__, vous êtes-vous assuré d'appeler la base threading.Thread.__init__()?

Après le démarrage des deux threads, le thread principal continue-t-il à travailler indéfiniment/bloquer/rejoindre sur les threads enfants afin que l'exécution du thread principal ne se termine pas avant que les threads enfants ne terminent leurs tâches?

Et enfin, obtenez-vous des exceptions non gérées?

2
Jeremy Brown

Python 3 a la facilité de Lancer des tâches parallèles . Cela facilite notre travail.

Il a pour pool de threads et pool de processus .

Ce qui suit donne un aperçu:

Exemple de 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 autre exemple

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 __== '__main__':
    main()
0
Jeril