Pythonでマルチスレッド
実行したいこと複数ある場合の実行方法について考えます。通常は命令の順番通りに実行していきます。複数実行したい場合でも一つ終わってから次の処理を行うことになります。この処理は同期処理と言います。
複数同時、割り込んで実行することを非同期処理と言います。この非同期処理ですが、複数の処理を完全に別に行うものと一つの処理の中で割り込みながら並行して行うものがあります。
複数同時に行う、別処理として行うことをマルチスレッドと呼ぶこともあります。
マルチスレッドの実現には"threading"を使用します。もう一つの非同期に処理ができる方法には"asyncio"を使用して実現します。
threading
"threading"を使わない方法。関数process()をそのまま書いて実行します。
import time
def process():
print('Process Start')
time.sleep(3)
print('Process End')
print('Main Start')
process()
time.sleep(1)
print('Main End')
process()で3秒、の次にtime.sleep(1)を実行するので約4秒かかります。
という順番に実行されます。上から順番に実行しているので最後に"Main End"が出力されます。順番、同期的な処理となります。
次に"threading"を使う方法
import threading
import time
def process():
print('Process Start')
time.sleep(3)
print('Process End')
print('Main Start')
threadA = threading.Thread(target=process)
threadA.start()
time.sleep(1)
threadA.join()
print('Main End')
・Main Start
・Process Start
・Main End
・Process End
この場合は"Process Start"で3秒待っている間に"time.sleep(1)"が実行されるので全体では約3秒で終了します。最後の処理も"Process End"となっていて、3秒終了と同時に出力(非同期、並列に処理)されていることがわかります。
asyncio
公式のドキュメントにもあるコードを実行します。
import asyncio
async def main():
print('Hello ...')
await asyncio.sleep(1)
print('... World!')
asyncio.run(main())
まず、VSCodeのjupyterの実行しようとするとエラーが出ます。調べて見ると
import asyncio
import datetime
async def display_date():
"""現在時刻を5秒間表示する"""
loop = asyncio.get_running_loop()
end_time = loop.time() + 5.0
while True:
print(datetime.datetime.now())
if(loop.time()+1.0)>=end_time:
break
await asyncio.sleep(1)
x : asyncio.run(display_date())
○ : await display_date()
ということらしいので
import asyncio
async def main():
print('Hello ...')
await asyncio.sleep(1)
print('... World!')
await main()
として実行するとうまくいきます。
以下のサイトでいろんなasyncioが紹介されています。
その中でうまく非同期処理されているものは
import asyncio
async def func1():
print('func1() started')
await asyncio.sleep(1)
print('func1() finished')
async def func2():
print('func2() started')
await asyncio.sleep(1)
print('func2() finished')
async def main():
task1 = asyncio.create_task(func1())
task2 = asyncio.create_task(func2())
await task1
await task2
await main()
実行すると、
func1() started
func2() started
func1() finished
func2() finished
と出力されます。非同期処理されほぼ同時に終わっています。うまくいっています。
うまくいかない場合、
import asyncio
import time
async def func1():
print('Process Star')
await asyncio.sleep(3)
print('Process End')
async def main():
print('Main Start')
task1 = asyncio.create_task(func1())
await task1
time.sleep(1)
print('Main End')
await main()
とすると、
Main Start
Process Star
Process End
Main End
asyncioで非同期の処理が終わってから"time.sleep(1)"が実行されてしまいます。これでは非同期処理としてはうまくいきません。
このことからasyncioは基本的にはシングルスレッドなのがわかります。
この記事が気に入ったらサポートをしてみませんか?