ホームページ >バックエンド開発 >Python チュートリアル >Pythonによるマルチプロセス・マルチスレッド例(2) プログラミング方法

Pythonによるマルチプロセス・マルチスレッド例(2) プログラミング方法

零下一度
零下一度オリジナル
2017-06-01 10:01:101762ブラウズ

前の章では、Python マルチプロセス プログラミングのいくつかの基本的な方法を学びました。クロスプラットフォームのマルチプロセス モジュール multiprocessing によって提供される Process、Pool、Queue、Lock、Pipe およびその他のクラスを使用して、サブプロセスの作成と実装を実装します。プロセス プール (バッチでサブプロセスを作成する)、子プロセスの最大数を処理および管理する)、およびプロセス間通信。この章では、Python のマルチスレッド プログラミング手法について学習します。

1. スレッド

スレッドは、オペレーティング システムがタスクを実行するための最小単位です。スレッド モジュールは Python 標準ライブラリで提供されており、マルチスレッド プログラミングに非常に便利なサポートを提供します。

以下は、スレッドを使用してマルチスレッドを実装するコードです:

 1 #!/usr/bin/python 2 # -*- coding: utf-8 -* 3 author = 'zni.feng' 4 import  sys 5 reload (sys) 6 sys.setdefaultencoding('utf-8') 7  8 import threading, time 9 10 def test(index):11     print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))12     print 'thread %s starts.' % threading.current_thread().name13     print 'the index is %d' % index14     time.sleep(3)15     print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))16     print 'thread %s ends.' % threading.current_thread().name17 18 if name == "main":19     print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))20     print 'thread %s starts.' % threading.current_thread().name21     #创建线程22     my_thread = threading.Thread(target = test, args=(1,) , name= 'zni_feng_thread')23     #等待2s24     time.sleep(2)25     #启动线程26     my_thread.start()27     #等待线程结束28     my_thread.join()29     print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))30     print 'thread %s ends.' % threading.current_thread().name

出力結果は次のとおりです:

2017-01-12 22:06:32
thread MainThread starts.
2017-01-12 22:06:34
thread zni_feng_thread starts.
the index is 1
2017-01-12 22:06:37
thread zni_feng_thread ends.
2017-01-12 22:06:37
thread MainThread ends.
[Finished in 5.1s]

このうち、スレッドモジュールのcurrent_thread()関数は、現在のスレッドのインスタンスを返します。

2. ロック

マルチプロセスとマルチスレッドの最大の違いは、マルチプロセスでは同じ変数が各プロセスにコピーを持ち、相互に影響を与えないことです。マルチスレッドでは、すべての変数がすべてのスレッドで共有されるため、どの共有変数もどのスレッドでも変更できます。したがって、スレッド間でデータを共有する際の最大の危険は、複数のスレッドが同時に変数を変更することです。この問題を解決するには、スレッド モジュールの Lock クラスを使用して共有変数をロックします。

まず、複数のスレッドを使用して、ロックせずに同じ共有変数を書き込む例を見てみましょう:

 1 #!/usr/bin/python 2 # -*- coding: utf-8 -* 3 author = 'zni.feng' 4 import  sys 5 reload (sys) 6 sys.setdefaultencoding('utf-8') 7 import threading 8  9 class Account:10     def init(self):11         self.balance = 012 13     def add(self):14         for i in range(0,100000):15             self.balance += 116 17     def delete(self):18         for i in range(0,100000):19             self.balance -=1 
20 21 if name == "main":22     account  = Account()23     #创建线程24     thread_add = threading.Thread(target=account.add, name= 'Add')25     thread_delete = threading.Thread(target=account.delete, name= 'Delete')26 27     #启动线程28     thread_add.start()29     thread_delete.start()30     31     #等待线程结束32     thread_add.join()33     thread_delete.join()34 35     print 'The final balance is: ' + str(account.balance)

実行結果は次のとおりです:

The final balance is: -51713
[Finished in 0.1s]

最終結果は実行するたびに異なることがわかります。 0ではありません。これは、異なるスレッドが同じ変数を同時に変更すると競合が発生し、一部の中間変数が順番に使用されないためです。

今度は、Lock を使用してプログラムをロックします:

 1 #!/usr/bin/python 2 # -*- coding: utf-8 -* 3 author = 'zni.feng' 4 import  sys 5 reload (sys) 6 sys.setdefaultencoding('utf-8') 7 import threading 8  9 class Account:10     def init(self):11         self.balance = 012 13     def add(self, lock):14         #获得锁15         lock.acquire()16         for i in range(0,100000):17             self.balance += 118         #释放锁19         lock.release()20 21     def delete(self, lock):22         #获得锁23         lock.acquire()24         for i in range(0,100000):25             self.balance -=1 
26         #释放锁27         lock.release()28 29 30 if name == "main":31     account  = Account()32     lock = threading.Lock()33     #创建线程34     thread_add = threading.Thread(target=account.add, args=(lock, ), name= 'Add')35     thread_delete = threading.Thread(target=account.delete, args=(lock, ), name= 'Delete')36 37     #启动线程38     thread_add.start()39     thread_delete.start()40     41     #等待线程结束42     thread_add.join()43     thread_delete.join()44 45     print 'The final balance is: ' + str(account.balance)

何度実行しても、バランスの結果が 0 であることがわかります。各バランス計算の結果を出力すると、一方のスレッドが実行を開始すると、もう一方のスレッドは前のスレッドの実行が終了する (正確には、lock.release() の実行が終了する) まで待機してから開始することもわかります。 。 埋め込む。

The final balance is: 0
[Finished in 0.1s]

【関連する推奨事項】

1. Python のマルチプロセスとマルチスレッドの例 (1)

2. Python ではマルチスレッドの代わりにマルチプロセスを使用することをお勧めしますか?マルチプロセスの使用が推奨される理由を共有します

3. Python ではマルチプロセスとマルチスレッドの方が速いですか?

4.

Python プロセス、スレッド、コルーチンの詳細な紹介

5.

Python 同時プログラミング スレッド プール/プロセス プール

以上がPythonによるマルチプロセス・マルチスレッド例(2) プログラミング方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。