Pythonでのスレッドの作成


177

スクリプトがあり、1つの関数を他の関数と同時に実行したい。

私が見たサンプルコード:

import threading

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

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

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

これを機能させるのに苦労しています。クラスではなくスレッド化された関数を使用してこれを実行したいと思います。

これは作業スクリプトです:

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'

回答:


323

Threadこれを機能させるためにのサブクラスを使用する必要はありません。以下に投稿する簡単な例を見て、その方法を確認してください。

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

ここでは、スレッドモジュールを使用して、通常の関数をターゲットとして呼び出すスレッドを作成する方法を示します。スレッドコンストラクターで必要な引数を渡す方法を確認できます。


私はこれを試しました。上記でスクリプトを追加しました。最初の関数と一緒に2番目の関数を実行する方法を教えてください。ありがとう
chrissygormley

6
@chrissygormley:join()は、最初のスレッドが終了するまでブロックします。
FogleBird 2010年

4
@chrissygormley:前述のように、参加しているスレッドが終了するまでブロックを結合するため、この場合、2番目の関数をターゲットとして2番目のスレッドを開始し、2つの関数を並べて実行します。それらが完了するまで待つだけです。
jkp

41
私は読んで保たれexitingexciting、私はより適切なとにかくだと思っています、。
Chase Roberts

42

コードにはいくつかの問題があります:

def MyThread ( threading.thread ):
  • 関数でサブクラス化することはできません。クラスでのみ
  • threading.threadではなく、threading.Threadが必要なサブクラスを使用する場合

関数だけでこれを実行したい場合は、2つのオプションがあります。

スレッディングあり:

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

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

スレッド付き:

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

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

以下のためのドキュメントthread.start_new_thread


2
2番目の引数は、次のタプルでなければなりませんthread.start_new_thread(function, args[, kwargs])
venkatvb

13

別のjoin()を追加しようとしましたが、うまくいったようです。ここにコードがあります

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

コンストラクタのtarget引数を使用して、のThread代わりに呼び出される関数を直接渡すことができますrun


2

run()メソッドをオーバーライドしましたか?オーバーライドした場合__init__、ベースを呼び出すことを確認しましたthreading.Thread.__init__()か?

2つのスレッドを開始した後、メインスレッドは子スレッド上で無期限にブロック/結合して、子スレッドがタスクを完了する前にメインスレッドの実行が終了しないようにしますか?

そして最後に、未処理の例外が発生していますか?


未処理の例外はなく、メインスレッドは30分間実行する必要があります。オーバーライドしませんでした__init__。次にrun()が必要ですか?ありがとう
chrissygormley 2010年

私はあなたの例がdef MyThread ( threading.thread )...であることに気づきました...それらはクラス定義であると思いました threading.threadをサブクラス化しtarget=Nonetargetargを使用して、または省略してスレッドオブジェクトを初期化する場合は、run()の実装が必要です。それ以外の場合、単純なタスクを別のスレッドで実行したいだけであれば、jkpの答えを参照してください。
ジェレミーブラウン、

0

Python 3には、並列タスク起動する機能があります。これにより、作業が簡単になります。

それはのために持っているスレッドプールおよびプロセス・プーリング

以下は洞察を与えます:

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

もう一つの例

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()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.