Python学習ノート(3)マルチスレッドの使用
9217 ワード
この節では,マルチスレッド学習の心得を記録する.
Pythonはthreadモジュールを提供していますが、このモジュールの欠点は多く、例えばスレッドの終了を容易に待つことができないため、より高度なthreadingモジュールを使用しています.
threadingモジュールの使用には、3つのモードがあります.
1.関数によるThreadインスタンスの生成
2.関数を使用して呼び出し可能なクラスオブジェクトを生成し、Threadインスタンスを生成する
3.Threadからサブクラスを派生し、このサブクラスのインスタンスを作成する
関数によるThreadインスタンスの生成
1つ目の使用方法は最も簡単で、コードは以下の通りです.
このコードの論理は簡単で、スレッドでthreadFuncという関数を実行します.
この関数にパラメータが必要な場合は、
次のように、この行にパラメータを追加します.
注意argsパラメータは、メタグループまたはリストを使用する必要があります.
関数を使用して呼び出し可能なクラスオブジェクトを生成し、Threadインスタンスを生成します.
C++に関数オブジェクトがあり、あるクラスのリロード関数にオペレータを呼び出すと、そのクラスのオブジェクトが関数として使用でき、pythonにも同様のメカニズムがあります.
この例ではfはオブジェクトですが、関数として使用できます.f()が呼び出されると、解釈器はFooの__を呼び出すcall__メソッドは、C++に相当するoperator()オペレータがリロードされます.
もう一つのapplyに関する知識点は、
applyはこのように関数を呼び出すことができます.このメカニズムにより,関数を格納し,適切なタイミングを選択して呼び出しに注意することができる.
これにより、クラスに関数を格納し、クラスに__を提供できます.call__関数は、このクラスのオブジェクトでも実行できるので、このオブジェクトを利用してThreadを生成します.
t 1はThreadFuncのインスタンスであり、直接実行することもできるし、Threadインスタンスを生成するために使用することもできる.
Threadからサブクラスが派生し、このサブクラスのインスタンスが作成されます.
最も簡単な使い方は次のとおりです.
Threadクラスを継承し、JavaのThreadの使用と一致するrunメソッドを上書きします.
複数のスレッドを作成するには、次のようにします.
しかし、現在、私たちのスレッドロジックは固定されており、第2の方法を参考にして、外部からロジックを転送し、記憶することができます.
2つ目とは違います
1.継承を採用し、ベースクラスはThread
2.runメソッドを上書きします.call__方法
3.使用時にクラスのインスタンスを直接作成する
以上の3つは、個人的には3つ目が一番便利だと思いますが、大きなプログラムでは、このThreadを単独でモジュールにすることができます.
また、前の2つの本質は同じであり、いずれもThreadに実行可能なオブジェクトが入力される(pythonでは関数もオブジェクトである).
終わります.
Pythonはthreadモジュールを提供していますが、このモジュールの欠点は多く、例えばスレッドの終了を容易に待つことができないため、より高度なthreadingモジュールを使用しています.
threadingモジュールの使用には、3つのモードがあります.
1.関数によるThreadインスタンスの生成
2.関数を使用して呼び出し可能なクラスオブジェクトを生成し、Threadインスタンスを生成する
3.Threadからサブクラスを派生し、このサブクラスのインスタンスを作成する
関数によるThreadインスタンスの生成
1つ目の使用方法は最も簡単で、コードは以下の通りです.
import threading
from time import sleep
def threadFunc():
i = 10;
while i > 0:
print 'i = %d' % i
i -= 1
if __name__ == '__main__':
t = threading.Thread(target = threadFunc)
t.start()
t.join()
このコードの論理は簡単で、スレッドでthreadFuncという関数を実行します.
この関数にパラメータが必要な場合は、
t = threading.Thread(target = threadFunc)
次のように、この行にパラメータを追加します.
import threading
from time import sleep
def threadFunc(i):
while i > 0:
print 'i = %d' % i
i -= 1
if __name__ == '__main__':
t = threading.Thread(target = threadFunc, args = [10])
t.start()
t.join()
注意argsパラメータは、メタグループまたはリストを使用する必要があります.
関数を使用して呼び出し可能なクラスオブジェクトを生成し、Threadインスタンスを生成します.
C++に関数オブジェクトがあり、あるクラスのリロード関数にオペレータを呼び出すと、そのクラスのオブジェクトが関数として使用でき、pythonにも同様のメカニズムがあります.
class Foo():
def __call__(self):
print 'foobar'
if __name__ == '__main__':
f = Foo()
f()
この例ではfはオブジェクトですが、関数として使用できます.f()が呼び出されると、解釈器はFooの__を呼び出すcall__メソッドは、C++に相当するoperator()オペレータがリロードされます.
もう一つのapplyに関する知識点は、
def test(i):
print 'i = %d' % i
if __name__ == '__main__':
apply(test, [1])
applyはこのように関数を呼び出すことができます.このメカニズムにより,関数を格納し,適切なタイミングを選択して呼び出しに注意することができる.
from random import randint
def foo(i):
print 'i = %d' % i
def bar(i):
print 'i*i = %d' % (i*i)
class Foo():
def __call__(self, i):
print 'foobar: %d' % i
if __name__ == '__main__':
funcs = [foo, bar, Foo()]
for func in funcs:
i = randint(1, 4)
apply(func, [i])
これにより、クラスに関数を格納し、クラスに__を提供できます.call__関数は、このクラスのオブジェクトでも実行できるので、このオブジェクトを利用してThreadを生成します.
#coding: utf-8
import threading
from time import sleep
class ThreadFunc(object):
def __init__(self, func, args):
self.func = func
self.args = args
def __call__(self):
apply(self.func, self.args)
def loop(i):
while i > 0:
print 'i = %d' % i
sleep(0.5)
i -= 1
if __name__ == '__main__':
print ' '
t1 = ThreadFunc(loop, [5])
t1()
print ' '
t2 = threading.Thread(target = t1)
t2.start()
t2.join()
print ' '
print ' '
t3 = threading.Thread(target = ThreadFunc(loop, [3]))
t3.start()
t3.join()
print ' '
t 1はThreadFuncのインスタンスであり、直接実行することもできるし、Threadインスタンスを生成するために使用することもできる.
Threadからサブクラスが派生し、このサブクラスのインスタンスが作成されます.
最も簡単な使い方は次のとおりです.
import threading
from time import sleep
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.count = 10
def run(self):
while self.count > 0:
print 'i = %d' % self.count
sleep(1)
self.count -= 1
if __name__ == '__main__':
t = MyThread();
t.start()
t.join()
Threadクラスを継承し、JavaのThreadの使用と一致するrunメソッドを上書きします.
複数のスレッドを作成するには、次のようにします.
import threading
from time import sleep
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
print 'begin .....'
sleep(5)
print 'end.....'
if __name__ == '__main__':
threads = []
for i in range(10):
t = MyThread()
threads.append(t)
for t in threads:
t.start()
for t in threads:
t.join()
しかし、現在、私たちのスレッドロジックは固定されており、第2の方法を参考にして、外部からロジックを転送し、記憶することができます.
#coding: utf-8
import threading
from time import sleep
class CustomThread(threading.Thread):
def __init__(self, func, args):
threading.Thread.__init__(self)
self.func = func
self.args = args
def run(self):
apply(self.func, self.args)
def loop(i):
while i > 0:
print 'i = %d' % i
sleep(0.5)
i -= 1
if __name__ == '__main__':
t = CustomThread(loop, [10])
t.start()
t.join()
2つ目とは違います
1.継承を採用し、ベースクラスはThread
2.runメソッドを上書きします.call__方法
3.使用時にクラスのインスタンスを直接作成する
以上の3つは、個人的には3つ目が一番便利だと思いますが、大きなプログラムでは、このThreadを単独でモジュールにすることができます.
また、前の2つの本質は同じであり、いずれもThreadに実行可能なオブジェクトが入力される(pythonでは関数もオブジェクトである).
終わります.