Python'da Konu Oluşturma


177

Ben bir komut dosyası var ve bir işlevi diğeri ile aynı zamanda çalıştırmak istiyorum.

Baktığım örnek kod:

import threading

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

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

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

Bu işi yaparken sorun yaşıyorum. Bu bir sınıf yerine bir dişli işlevi kullanarak devam etmeyi tercih ederim.

Bu çalışma betiğidir:

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'

Yanıtlar:


323

Bu işi yapmak için bir alt sınıf kullanmanıza gerek yok Thread- nasıl gönderdiğini görmek için aşağıda gönderdiğim basit örneğe bir göz atın:

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

Burada, normal bir işlevi hedef olarak çağıran bir iş parçacığı oluşturmak için iş parçacığı modülünün nasıl kullanılacağını gösterir. Eğer iplik yapıcı içinde ona ihtiyacım ne olursa olsun nasıl aktarabilirsiniz görebilirsiniz.


Bunu denedim. Yukarıda komut dosyası ekledim. Bana ikinci fonksiyonun birincisiyle birlikte nasıl çalışacağını söyleyebilir misiniz? Teşekkürler
chrissygormley

6
@chrissygormley: ilk iş parçacığı bitene kadar join () bloklarını birleştirir.
FogleBird

4
@chrissygormley: belirtildiği gibi, birleştirdiğiniz iş parçacığı bitene kadar blokları birleştirin, bu durumda, iki işlevi yan yana çalıştırmak için ikinci işlevinizle hedef olarak ikinci bir iş parçacığı başlatın, ardından isteğe bağlı olarak bunlardan birine katılın bitene kadar beklemek istiyorsunuz.
jkp

41
Zaten daha uygun olduğunu düşündüğüm exitinggibi okumaya devam excitingettim.
Chase Roberts

42

Kodunuzla ilgili birkaç sorun var:

def MyThread ( threading.thread ):
  • Bir işlevle alt sınıf yapamazsınız; sadece bir sınıfla
  • Eğer bir alt sınıf kullanacak olsaydınız, iş parçacığı oluşturmak değil, iş parçacığı.

Bunu gerçekten yalnızca işlevlerle yapmak istiyorsanız, iki seçeneğiniz vardır:

Diş açma ile:

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

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

İplik ile:

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

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

Thread.start_new_thread için doküman


2
İkinci argüman a olmalıdır tuple içinthread.start_new_thread(function, args[, kwargs])
venkatvb

13

Başka bir join () eklemeye çalıştım ve işe yaramış gibi görünüyor. İşte kod

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

Doğrudan yerine çağrılan bir işlevi iletmek targetiçin Threadyapıcıdaki bağımsız değişkeni kullanabilirsiniz run.


2

Run () yöntemini geçersiz kıldınız mı? Geçersiz kıldığınızda __init__, üssü aradığınızdan emin misiniz threading.Thread.__init__()?

İki iş parçacığı başlatıldıktan sonra, ana iş parçacığı, alt iş parçacığı görevlerini tamamlamadan önce ana iş parçacığı yürütme sona ermeyecek şekilde alt iş parçacığı üzerinde süresiz olarak çalışma / engelleme / birleştirme devam ediyor mu?

Ve son olarak, ele alınmayan istisnalar var mı?


İşlenmeyen istisnalar yoktur ve ana iş parçacığı 30 dakika boyunca çalışmalıdır. Geçersiz kılmadım __init__. O halde run () gerekli mi? Teşekkürler
chrissygormley

Örneđin olduđunu fark ettim def MyThread ( threading.thread )... Bunlarýn sýnýf tanýmlarý olduđunu varsaydým. Threading.thread öğesini alt sınıfa taşıyacak ve argümanla iş parçacığı nesnesini başlatacak target=Noneveya targetatlayacaksanız, run () uygulamasının uygulanması gerekir. Aksi takdirde, yalnızca başka bir iş parçacığında basit bir görev çalıştırmak istiyorsanız, jkp'nin yanıtına bakın.
Jeremy Brown

0

Python 3, paralel görevleri başlatma imkanına sahiptir . Bu işimizi kolaylaştırır.

İş parçacığı havuzu ve İşlem havuzu için vardır .

Aşağıdakiler bir fikir verir:

ThreadPoolExecutor Örneği

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

Başka bir örnek

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()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.