[Python] 병렬 동시 처리 메모
참고한 기사
구체적인 예에서 이해하고 싶을 때 읽기
→ 파이썬 병렬 및 병렬 처리 샘플 코드 요약
어떤 때 사용하는지 고민했을 때 읽기
→ Python의 비동기 처리 : asyncio 역방향 참조
이론을 배우다
Python에는 threading, multiprocessing, asyncio와 모두 병렬 처리에 사용할 수 있는 패키지가 3개 있습니다. 이러한 차이를 먼저 누른다.
이러한 패키지의 차이는 그대로 "멀티 스레드", "멀티 프로세스", "논 블로킹"의 차이에 해당합니다. 첫째, 멀티 스레드와 멀티 프로세스의 차이점에 대해.
프로세스 풀
스레드가 아닌 프로세스 단위로 나누면 Global Interpreter Lock(GIL)의 제약을 받지 않게 되어 멀티 코어로 움직일 수 있게 됩니다.
그러나 그만큼 스레드보다 규모가 큰 프로세스를 사용하기 때문에 다른 제약이 늘어날 수도 있습니다. 주의!
import time
import concurrent.futures
def func1():
while True:
print("func1")
time.sleep(1)
def func2():
while True:
print("func2")
time.sleep(1)
if __name__ == "__main__":
executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)
for i in range(10):
if i % 2 == 0:
executor.submit(func1)
else:
executor.submit(func2)
print('loop end')
작업자를 4로 하면 4개 이상 프로세스가 기동하지 않는 것을 알 수 있다func1
func2
func1
func2
loop end
func1
func2
.
.
.
여러 프로세스에 여러 스레드를 구축
멀티 태스킹을 실현하는 데 도움이되는 관계 다이어그램
출처 : h tps : // s ぃ에서 sp ぁ ぇ r. 네 t/sぃ로/11222023/
"""
プロセス1にスレッド2つ起動
プロセス2にスレッド2つ起動
目標
① 同じプロセスにあるスレッド間のデータ共有 (スレッド間通信)
② 異なるプロセス間のデータ共有 (プロセス間通信)
"""
import time
import threading
from multiprocessing import Process, Value
from functools import partial
class PS():
# def __init__(self,ps_name,sl2,shm):
def __init__(self,ps_name,sl2):
self.ps_name=ps_name
self.sl2=sl2
self.is_quitting=False # ① スレッド間通信
# self.shm=shm # ② プロセス間通信
self.th1=threading.Thread(target=self.fn1)
self.th2=threading.Thread(target=self.fn2)
# 各スレッドの起動
print(f'{self.ps_name}: 1つ目のスレッド 起動')
self.th1.start()
print(f'{self.ps_name}: 2つ目のスレッド 起動')
self.th2.start()
print(f'現在起動中のスレッド: {threading.active_count()}')
# 各スレッドの終了を待つ
self.th1.join()
print(f'{self.ps_name}: 1つ目のスレッド 停止')
self.th2.join()
print(f'{self.ps_name}: 2つ目のスレッド 停止')
print(f'現在起動中のスレッド: {threading.active_count()}')
# このプロセスが終了したことを他のプロセスへ知らせる
# self.shm.value=1 # ② プロセス間通信
shm.value=1 # ② プロセス間通信
def fn1(self):
"""
終了フラグが立つまで1秒間隔で標準出力する
"""
time.sleep(1)
while not self.is_quitting: # ① スレッド間通信
print(f'{self.ps_name}: fn1: 実行中')
# if self.shm.value:
if shm.value:
print(f'{self.ps_name}: どこかのプロセスが終了している') # ② プロセス間通信
time.sleep(1)
def fn2(self):
"""
スレッド2が起動して数秒後にスレッド1を終了させるためのフラグを立てる
"""
time.sleep(self.sl2)
print(f'{self.ps_name}: fn2: 実行中')
self.is_quitting=True # ① スレッド間通信
print(f'\n{self.ps_name}: {self.ps_name}のfn1を終了します\n')
# 標準出力でプロセスを識別するために使う
name_ps1='プロセス1'
name_ps2='プロセス2'
# 共有メモリ(shared memory)
"""
メインスレッドで作成された共有メモリは、共有されるオブジェクトとなるので、引数で渡したり返却値に指定したりは不要
"""
shm = Value('i', 0) # 第一引数のiはc言語のint型を表す (詳しくはctypesで検索)
# プロセス1
# process1 = Process(target=PS, args=(name_ps1,2,shm)) # プロセス起動後2秒後にプロセス終了
process1 = Process(target=PS, args=(name_ps1,2)) # プロセス起動後2秒後にプロセス終了
# プロセス2
# process2 = Process(target=PS, args=(name_ps2,7,shm)) # プロセス起動後5秒後にプロセス終了
process2 = Process(target=PS, args=(name_ps2,7)) # プロセス起動後5秒後にプロセス終了
print(f'{name_ps1}: start')
process1.start()
print(f'{name_ps2}: start')
process2.start()
process1.join()
print(f'\n{name_ps1}: end\n')
process2.join()
print(f'\n{name_ps2}: end\n')
プロセス1: start
プロセス2: start
プロセス1: 1つ目のスレッド 起動
プロセス1: 2つ目のスレッド 起動
プロセス2: 1つ目のスレッド 起動
プロセス2: 2つ目のスレッド 起動
プロセス1: fn1: 実行中
プロセス2: fn1: 実行中
プロセス1: fn1: 実行中
プロセス1: fn2: 実行中
プロセス1: プロセス1のfn1を終了します
プロセス2: fn1: 実行中
プロセス1: 1つ目のスレッド 停止
プロセス1: 2つ目のスレッド 停止
プロセス2: fn1: 実行中
プロセス2: どこかのプロセスが終了している
プロセス1: end
プロセス2: fn1: 実行中
プロセス2: どこかのプロセスが終了している
プロセス2: fn1: 実行中
プロセス2: どこかのプロセスが終了している
プロセス2: fn1: 実行中
プロセス2: どこかのプロセスが終了している
プロセス2: fn2: 実行中
プロセス2: プロセス2のfn1を終了します
プロセス2: 1つ目のスレッド 停止
プロセス2: 2つ目のスレッド 停止
プロセス2: end
Reference
이 문제에 관하여([Python] 병렬 동시 처리 메모), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/osorezugoing/items/bac7576b1cde7929f818
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Python에는 threading, multiprocessing, asyncio와 모두 병렬 처리에 사용할 수 있는 패키지가 3개 있습니다. 이러한 차이를 먼저 누른다.
이러한 패키지의 차이는 그대로 "멀티 스레드", "멀티 프로세스", "논 블로킹"의 차이에 해당합니다. 첫째, 멀티 스레드와 멀티 프로세스의 차이점에 대해.
프로세스 풀
스레드가 아닌 프로세스 단위로 나누면 Global Interpreter Lock(GIL)의 제약을 받지 않게 되어 멀티 코어로 움직일 수 있게 됩니다.
그러나 그만큼 스레드보다 규모가 큰 프로세스를 사용하기 때문에 다른 제약이 늘어날 수도 있습니다. 주의!
import time
import concurrent.futures
def func1():
while True:
print("func1")
time.sleep(1)
def func2():
while True:
print("func2")
time.sleep(1)
if __name__ == "__main__":
executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)
for i in range(10):
if i % 2 == 0:
executor.submit(func1)
else:
executor.submit(func2)
print('loop end')
작업자를 4로 하면 4개 이상 프로세스가 기동하지 않는 것을 알 수 있다func1
func2
func1
func2
loop end
func1
func2
.
.
.
여러 프로세스에 여러 스레드를 구축
멀티 태스킹을 실현하는 데 도움이되는 관계 다이어그램
출처 : h tps : // s ぃ에서 sp ぁ ぇ r. 네 t/sぃ로/11222023/
"""
プロセス1にスレッド2つ起動
プロセス2にスレッド2つ起動
目標
① 同じプロセスにあるスレッド間のデータ共有 (スレッド間通信)
② 異なるプロセス間のデータ共有 (プロセス間通信)
"""
import time
import threading
from multiprocessing import Process, Value
from functools import partial
class PS():
# def __init__(self,ps_name,sl2,shm):
def __init__(self,ps_name,sl2):
self.ps_name=ps_name
self.sl2=sl2
self.is_quitting=False # ① スレッド間通信
# self.shm=shm # ② プロセス間通信
self.th1=threading.Thread(target=self.fn1)
self.th2=threading.Thread(target=self.fn2)
# 各スレッドの起動
print(f'{self.ps_name}: 1つ目のスレッド 起動')
self.th1.start()
print(f'{self.ps_name}: 2つ目のスレッド 起動')
self.th2.start()
print(f'現在起動中のスレッド: {threading.active_count()}')
# 各スレッドの終了を待つ
self.th1.join()
print(f'{self.ps_name}: 1つ目のスレッド 停止')
self.th2.join()
print(f'{self.ps_name}: 2つ目のスレッド 停止')
print(f'現在起動中のスレッド: {threading.active_count()}')
# このプロセスが終了したことを他のプロセスへ知らせる
# self.shm.value=1 # ② プロセス間通信
shm.value=1 # ② プロセス間通信
def fn1(self):
"""
終了フラグが立つまで1秒間隔で標準出力する
"""
time.sleep(1)
while not self.is_quitting: # ① スレッド間通信
print(f'{self.ps_name}: fn1: 実行中')
# if self.shm.value:
if shm.value:
print(f'{self.ps_name}: どこかのプロセスが終了している') # ② プロセス間通信
time.sleep(1)
def fn2(self):
"""
スレッド2が起動して数秒後にスレッド1を終了させるためのフラグを立てる
"""
time.sleep(self.sl2)
print(f'{self.ps_name}: fn2: 実行中')
self.is_quitting=True # ① スレッド間通信
print(f'\n{self.ps_name}: {self.ps_name}のfn1を終了します\n')
# 標準出力でプロセスを識別するために使う
name_ps1='プロセス1'
name_ps2='プロセス2'
# 共有メモリ(shared memory)
"""
メインスレッドで作成された共有メモリは、共有されるオブジェクトとなるので、引数で渡したり返却値に指定したりは不要
"""
shm = Value('i', 0) # 第一引数のiはc言語のint型を表す (詳しくはctypesで検索)
# プロセス1
# process1 = Process(target=PS, args=(name_ps1,2,shm)) # プロセス起動後2秒後にプロセス終了
process1 = Process(target=PS, args=(name_ps1,2)) # プロセス起動後2秒後にプロセス終了
# プロセス2
# process2 = Process(target=PS, args=(name_ps2,7,shm)) # プロセス起動後5秒後にプロセス終了
process2 = Process(target=PS, args=(name_ps2,7)) # プロセス起動後5秒後にプロセス終了
print(f'{name_ps1}: start')
process1.start()
print(f'{name_ps2}: start')
process2.start()
process1.join()
print(f'\n{name_ps1}: end\n')
process2.join()
print(f'\n{name_ps2}: end\n')
プロセス1: start
プロセス2: start
プロセス1: 1つ目のスレッド 起動
プロセス1: 2つ目のスレッド 起動
プロセス2: 1つ目のスレッド 起動
プロセス2: 2つ目のスレッド 起動
プロセス1: fn1: 実行中
プロセス2: fn1: 実行中
プロセス1: fn1: 実行中
プロセス1: fn2: 実行中
プロセス1: プロセス1のfn1を終了します
プロセス2: fn1: 実行中
プロセス1: 1つ目のスレッド 停止
プロセス1: 2つ目のスレッド 停止
プロセス2: fn1: 実行中
プロセス2: どこかのプロセスが終了している
プロセス1: end
プロセス2: fn1: 実行中
プロセス2: どこかのプロセスが終了している
プロセス2: fn1: 実行中
プロセス2: どこかのプロセスが終了している
プロセス2: fn1: 実行中
プロセス2: どこかのプロセスが終了している
プロセス2: fn2: 実行中
プロセス2: プロセス2のfn1を終了します
プロセス2: 1つ目のスレッド 停止
プロセス2: 2つ目のスレッド 停止
プロセス2: end
Reference
이 문제에 관하여([Python] 병렬 동시 처리 메모), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/osorezugoing/items/bac7576b1cde7929f818
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import time
import concurrent.futures
def func1():
while True:
print("func1")
time.sleep(1)
def func2():
while True:
print("func2")
time.sleep(1)
if __name__ == "__main__":
executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)
for i in range(10):
if i % 2 == 0:
executor.submit(func1)
else:
executor.submit(func2)
print('loop end')
func1
func2
func1
func2
loop end
func1
func2
.
.
.
멀티 태스킹을 실현하는 데 도움이되는 관계 다이어그램
출처 : h tps : // s ぃ에서 sp ぁ ぇ r. 네 t/sぃ로/11222023/
"""
プロセス1にスレッド2つ起動
プロセス2にスレッド2つ起動
目標
① 同じプロセスにあるスレッド間のデータ共有 (スレッド間通信)
② 異なるプロセス間のデータ共有 (プロセス間通信)
"""
import time
import threading
from multiprocessing import Process, Value
from functools import partial
class PS():
# def __init__(self,ps_name,sl2,shm):
def __init__(self,ps_name,sl2):
self.ps_name=ps_name
self.sl2=sl2
self.is_quitting=False # ① スレッド間通信
# self.shm=shm # ② プロセス間通信
self.th1=threading.Thread(target=self.fn1)
self.th2=threading.Thread(target=self.fn2)
# 各スレッドの起動
print(f'{self.ps_name}: 1つ目のスレッド 起動')
self.th1.start()
print(f'{self.ps_name}: 2つ目のスレッド 起動')
self.th2.start()
print(f'現在起動中のスレッド: {threading.active_count()}')
# 各スレッドの終了を待つ
self.th1.join()
print(f'{self.ps_name}: 1つ目のスレッド 停止')
self.th2.join()
print(f'{self.ps_name}: 2つ目のスレッド 停止')
print(f'現在起動中のスレッド: {threading.active_count()}')
# このプロセスが終了したことを他のプロセスへ知らせる
# self.shm.value=1 # ② プロセス間通信
shm.value=1 # ② プロセス間通信
def fn1(self):
"""
終了フラグが立つまで1秒間隔で標準出力する
"""
time.sleep(1)
while not self.is_quitting: # ① スレッド間通信
print(f'{self.ps_name}: fn1: 実行中')
# if self.shm.value:
if shm.value:
print(f'{self.ps_name}: どこかのプロセスが終了している') # ② プロセス間通信
time.sleep(1)
def fn2(self):
"""
スレッド2が起動して数秒後にスレッド1を終了させるためのフラグを立てる
"""
time.sleep(self.sl2)
print(f'{self.ps_name}: fn2: 実行中')
self.is_quitting=True # ① スレッド間通信
print(f'\n{self.ps_name}: {self.ps_name}のfn1を終了します\n')
# 標準出力でプロセスを識別するために使う
name_ps1='プロセス1'
name_ps2='プロセス2'
# 共有メモリ(shared memory)
"""
メインスレッドで作成された共有メモリは、共有されるオブジェクトとなるので、引数で渡したり返却値に指定したりは不要
"""
shm = Value('i', 0) # 第一引数のiはc言語のint型を表す (詳しくはctypesで検索)
# プロセス1
# process1 = Process(target=PS, args=(name_ps1,2,shm)) # プロセス起動後2秒後にプロセス終了
process1 = Process(target=PS, args=(name_ps1,2)) # プロセス起動後2秒後にプロセス終了
# プロセス2
# process2 = Process(target=PS, args=(name_ps2,7,shm)) # プロセス起動後5秒後にプロセス終了
process2 = Process(target=PS, args=(name_ps2,7)) # プロセス起動後5秒後にプロセス終了
print(f'{name_ps1}: start')
process1.start()
print(f'{name_ps2}: start')
process2.start()
process1.join()
print(f'\n{name_ps1}: end\n')
process2.join()
print(f'\n{name_ps2}: end\n')
プロセス1: start
プロセス2: start
プロセス1: 1つ目のスレッド 起動
プロセス1: 2つ目のスレッド 起動
プロセス2: 1つ目のスレッド 起動
プロセス2: 2つ目のスレッド 起動
プロセス1: fn1: 実行中
プロセス2: fn1: 実行中
プロセス1: fn1: 実行中
プロセス1: fn2: 実行中
プロセス1: プロセス1のfn1を終了します
プロセス2: fn1: 実行中
プロセス1: 1つ目のスレッド 停止
プロセス1: 2つ目のスレッド 停止
プロセス2: fn1: 実行中
プロセス2: どこかのプロセスが終了している
プロセス1: end
プロセス2: fn1: 実行中
プロセス2: どこかのプロセスが終了している
プロセス2: fn1: 実行中
プロセス2: どこかのプロセスが終了している
プロセス2: fn1: 実行中
プロセス2: どこかのプロセスが終了している
プロセス2: fn2: 実行中
プロセス2: プロセス2のfn1を終了します
プロセス2: 1つ目のスレッド 停止
プロセス2: 2つ目のスレッド 停止
プロセス2: end
Reference
이 문제에 관하여([Python] 병렬 동시 처리 메모), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/osorezugoing/items/bac7576b1cde7929f818텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)