Erstellen von Threads in Python

176

Ich habe ein Skript und möchte, dass eine Funktion gleichzeitig mit der anderen ausgeführt wird.

Der Beispielcode, den ich mir angesehen habe:

import threading

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

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

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

Ich habe Probleme damit. Ich würde es vorziehen, dies mit einer Thread-Funktion anstelle einer Klasse in Gang zu bringen.

Dies ist das Arbeitsskript:

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'
chrissygormley
quelle

Antworten:

319

Sie müssen keine Unterklasse von verwenden Thread, damit dies funktioniert. Sehen Sie sich das einfache Beispiel an, das ich unten veröffentliche, um zu sehen, wie:

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

Hier zeige ich, wie man mit dem Threading-Modul einen Thread erstellt, der eine normale Funktion als Ziel aufruft. Sie können sehen, wie ich alle erforderlichen Argumente im Thread-Konstruktor übergeben kann.

jkp
quelle
Ich habe es versucht. Ich habe das Skript oben hinzugefügt. Können Sie mir sagen, wie die zweite Funktion neben der ersten ausgeführt werden kann? Danke
chrissygormley
6
@chrissygormley: join () blockiert, bis der erste Thread beendet ist.
FogleBird
4
@chrissygormley: Wie bereits erwähnt, verbinden Sie Blöcke, bis der Thread, den Sie verbinden, fertig ist. Starten Sie in Ihrem Fall einen zweiten Thread mit Ihrer zweiten Funktion als Ziel, um die beiden Funktionen nebeneinander auszuführen, und verbinden Sie dann optional eine davon, wenn Sie möchten nur warten, bis sie fertig sind.
JKP
41
Ich las weiter exitingals exciting, was ich sowieso für angemessener hielt.
Chase Roberts
42

Es gibt einige Probleme mit Ihrem Code:

def MyThread ( threading.thread ):
  • Sie können keine Unterklasse mit einer Funktion erstellen. nur mit einer Klasse
  • Wenn Sie eine Unterklasse verwenden möchten, möchten Sie threading.Thread, nicht threading.thread

Wenn Sie dies wirklich nur mit Funktionen tun möchten, haben Sie zwei Möglichkeiten:

Mit Einfädeln:

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

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

Mit Faden:

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

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

Dokument für thread.start_new_thread

Jorenko
quelle
2
Das zweite Argument muss ein Tupel fürthread.start_new_thread(function, args[, kwargs])
venkatvb
13

Ich habe versucht, einen weiteren Join () hinzuzufügen, und es scheint funktioniert zu haben. Hier ist 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()
GGG
quelle
3

Sie können das targetArgument im ThreadKonstruktor verwenden, um direkt eine Funktion zu übergeben, die anstelle von aufgerufen wird run.

unholysampler
quelle
2

Haben Sie die run () -Methode überschrieben? Wenn Sie überschrieben haben __init__, haben Sie sichergestellt, dass Sie die Basis anrufen threading.Thread.__init__()?

Funktioniert der Hauptthread nach dem Starten der beiden Threads weiterhin auf unbestimmte Zeit / blockiert / verbindet die untergeordneten Threads, sodass die Ausführung des Hauptthreads nicht endet, bevor die untergeordneten Threads ihre Aufgaben abgeschlossen haben?

Und schließlich, bekommen Sie unbehandelte Ausnahmen?

Jeremy Brown
quelle
Es gibt keine nicht behandelten Ausnahmen und der Hauptthread sollte 30 Minuten lang ausgeführt werden. Ich habe nicht überschrieben __init__. Ist run () dann erforderlich? Danke
chrissygormley
Ich habe gerade festgestellt, dass Ihr Beispiel def MyThread ( threading.thread )... Ich habe angenommen, dass dies Klassendefinitionen sind. Wenn Sie threading.thread in eine Unterklasse verschieben und das Thread-Objekt mit target=Nonedem targetArgument initialisieren oder weglassen möchten, ist eine Implementierung von run () erforderlich. Wenn Sie andernfalls nur eine einfache Aufgabe in einem anderen Thread ausführen möchten, lesen Sie die Antwort von jkp.
Jeremy Brown
0

Python 3 bietet die Möglichkeit, parallele Aufgaben zu starten . Dies erleichtert unsere Arbeit.

Es hat für Thread-Pooling und Prozess-Pooling .

Folgendes gibt einen Einblick:

ThreadPoolExecutor-Beispiel

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

Ein anderes Beispiel

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
quelle