Python 감지 스 레 드 상 태 를 분석 하 는 솔 루 션 의 이벤트 와 신 호 량
6167 단어 python감지 스 레 드 상태Event신호 량
Threading 라 이브 러 리 를 이용 하여 우 리 는 편리 하 게 스 레 드 를 만 들 고 우리 가 하고 싶 은 일 을 수행 하여 프로그램 운행 의 효율 을 가속 화 할 수 있 습 니 다.그러나 한 가 지 는 스 레 드 가 만들어 진 후에 운영 체제 에 맡 겼 다 는 것 이다.우 리 는 스 레 드 를 직접 끝 낼 수도 없고 신 호 를 보 낼 수도 없고 스케줄 을 조정 할 수도 없고 다른 고급 조작 도 없다.관련 기능 을 원한 다 면,스스로 개발 할 수 밖 에 없다.
어떻게 개발 할 까요?
우리 가 스 레 드 를 만 들 때 target 은 우리 가 실행 하고 자 하 는 함수 와 같 습 니 다.이 함 수 는 반드시 전체 함수 가 아니 라 실제 적 으로 대상 중의 함수 일 수도 있 습 니 다.대상 중의 함수 라면 우 리 는 이 함수 에서 대상 중의 다른 정 보 를 얻 을 수 있 습 니 다.우 리 는 이 점 을 이용 하여 수 동 제어 스 레 드 의 정 지 를 실현 할 수 있 습 니 다.
말하자면 이해 하기 어 려 울 것 같 지만 코드 를 보면 정말 간단 합 니 다.
import time
from threading import Thread
class TaskWithSwitch:
def __init__(self):
self._running = True
def terminate(self):
self._running = False
def run(self, n):
while self._running and n > 0:
print('Running {}'.format(n))
n -= 1
time.sleep(1)
c = TaskWithSwitch()
t = Thread(target=c.run, args=(10, ))
t.start()
c.terminate()
t.join()
이 코드 를 실행 하면 화면 에 10 만 출력 되 어 있 습 니 다.왜냐하면 우 리 는running 이 필드 를 False 로 설정 한 후 다음 순환 할 때 순환 조건 을 만족 시 키 지 않 으 면 스스로 종료 합 니 다.만약 우리 가 다 중 스 레 드 로 IO 를 읽 으 려 고 한다 면,IO 가 막 힐 수 있 기 때문에 스 레 드 가 되 돌아 오지 못 하 는 상황 이 발생 할 수 있 습 니 다.그 러 니까 우 리 는 순환 내부 에서 끊 겨 죽 었 다 는 거 야.이 럴 때 는 그냥running 으로 판단 하 는 것 이 부족 합 니 다.우 리 는 스 레 드 내부 에 타 이 머 를 설치 하여 내부 의 카드 사 를 방지 해 야 합 니 다.
class IOTask:
def __init__(self):
self._running = True
def terminate(self):
self._running = False
def run(self, sock):
# socket
sock.settimeout(10)
while self._running:
try:
# ,
data = sock.recv(1024)
break
except socket.timeout:
continue
return
2.스 레 드 신호 전달우리 가 이렇게 힘 들 어야 스 레 드 의 운행 을 통제 할 수 있 는 이 유 는 스 레 드 의 상 태 를 알 수 없고 우 리 는 그것 을 직접 조작 할 수 없 기 때문이다.왜냐하면 그것 은 운영 체제 에 의 해 관리 되 기 때문이다.우리 가 실행 하 는 메 인 스 레 드 와 만들어 진 스 레 드 는 독립 적 이 고 이들 사이 에 종속 관계 가 없 기 때문에 스 레 드 의 상 태 를 통제 하려 면 우리 가 다른 수단 을 통 해 이 루어 져 야 한다.
우 리 는 한 장면 을 생각해 보 자.만약 에 우리 가 임무 가 있다 고 가정 하면 다른 라인 의 운행 이 끝 난 후에 야 실행 을 시작 할 수 있다.이 를 실현 하려 면 스 레 드 의 상 태 를 감지 하고 다른 스 레 드 가 신 호 를 전달 해 야 한다.우 리 는 threading 의 이벤트 도 구 를 사용 하여 이 점 을 실현 할 수 있다.이벤트 도 구 는 신 호 를 전달 하 는 데 사용 할 수 있 습 니 다.마치 하나의 스위치 인 것 같 습 니 다.하나의 스 레 드 가 실 행 된 후에 이 스위치 를 시작 합 니 다.이 스위치 는 또 다른 논리 적 운행 을 제어 하고 있다.
다음 샘플 코드 를 살 펴 보 겠 습 니 다.
import time
from threading import Thread, Event
def run_in_thread():
time.sleep(1)
print('Thread is running')
t = Thread(target=run_in_thread)
t.start()
print('Main thread print')
우 리 는 스 레 드 에서 한 줄 의 프롬프트 만 출력 했 을 뿐 다른 논리 가 없 었 다.왜냐하면 우 리 는 runin_thread 함수 에 1s 가 잠 들 었 기 때문에 Main thread print 를 먼저 출력 하고 출력 하 는 Thread is running 이 분명 합 니 다.만약 에 이 스 레 드 가 매우 중요 한 임무 라 고 가정 하면 우 리 는 메 인 스 레 드 가 한 단계 까지 실행 되 기 를 기다 리 고 내 려 갈 수 있 기 를 바 랍 니 다.우 리 는 어떻게 해 야 합 니까?여기 서 말 하 는 것 은 한 단계 까지 운행 하 는 것 이지 운행 이 끝 난 것 이 아 닙 니 다.실행 이 끝나 면 우 리 는 잘 처리 할 수 있 습 니 다.join 을 통 해 완성 할 수 있 습 니 다.그러나 운행 이 끝 난 것 이 아니 라 운행 이 어느 단 계 를 완성 했다 면 물론 join 을 통 해 도 되 지만 전체적인 효율 을 해 칠 수 있다.이 럴 때 우 리 는 이 벤트 를 써 야 한다.이벤트 가 추 가 된 후에 코드 를 다시 보 겠 습 니 다.
import time
from threading import Thread, Event
def run_in_thread(event):
time.sleep(1)
print('Thread is running')
# set event, wait
event.set()
# Event
event = Event()
t = Thread(target=run_in_thread, args=(event, ))
t.start()
# event set
event.wait()
print('Main thread print')
전체적인 논 리 는 그다지 수정 되 지 않 았 는데,주로 이벤트 에 관 한 몇 줄 의 사용 코드 를 추가 하 였 다.이벤트 에 사용 하려 면 코드 에서 한 번 만 사용 하 는 것 이 좋 습 니 다.물론 이벤트 의 clear 방법 을 통 해 이벤트 의 값 을 리 셋 할 수 있 지만 문 제 는 리 셋 된 이 논리 가 wait 전에 실 행 될 것 이 라 고 보장 할 수 없다 는 것 입 니 다.나중에 실행 된다 면 문제 가 되 고 debug 에서 매우 고 통 스 러 울 수 있 습 니 다.bug 는 반드시 나타 나 는 것 이 아니 라 가끔 나타 나 거나 나타 나 지 않 기 때 문 입 니 다.이런 상황 은 종종 다 중 스 레 드 의 사용 문제 때문이다.
따라서 스위치 와 신 호 를 여러 번 사용 하려 면 Event 를 사용 하지 말고 신 호 량 을 사용 할 수 있 습 니 다.
신호 량
이벤트 의 문 제 는 여러 스 레 드 가 이벤트 의 발생 을 기다 리 고 있 으 면 set 가 되면 이 스 레 드 가 동시에 실 행 됩 니 다.그러나 때때로 우 리 는 이렇게 하 기 를 원 하지 않 는 다.우 리 는 이 라인 들 이 하나하나 운행 하 는 것 을 통제 할 수 있 기 를 바란다.이 를 위해 서 는 이벤트 가 만족 하지 못 하고 신 호 량 을 사용 해 야 한다.
신 호 량 은 Event 의 사용 방법 과 유사 합 니 다.다른 것 은 신 호 량 은 매번 하나의 스 레 드 만 작 동 하도록 보장 할 수 있 습 니 다.이 두 가지 바 텀 논리 가 일치 하지 않 기 때문에 Event 에 있어 서 는 스위치 와 같다.스위치 가 시작 되면 이 스위치 와 관련 된 모든 논리 가 동시에 실 행 됩 니 다.신 호 량 은 허가증 처럼 허가증 을 받 은 스 레 드 만 작업 을 수행 할 수 있 고 허가증 은 한 번 에 한 장 만 발급 할 수 있다.
신 호 량 을 사용 하려 면 스스로 개발 할 필요 가 없습니다.thread 라 이브 러 리 에서 기 존의 도구 인 Semaphore 를 제 공 했 습 니 다.사용 코드 를 보 겠 습 니 다.
#
def worker(n, sema):
#
sema.acquire()
print('Working', n)
#
sema = threading.Semaphore(0)
nworkers = 10
for n in range(nworkers):
t = threading.Thread(target=worker, args=(n, sema,))
t.start()
위의 코드 에서 우 리 는 10 개의 스 레 드 를 만 들 었 습 니 다.비록 이 스 레 드 가 모두 시작 되 었 지만 논 리 를 실행 하지 않 습 니 다.sema.acquire 는 차단 방법 이기 때문에 신 호 량 을 감지 하지 못 하면 계속 걸 려 서 기다 릴 것 입 니 다.우리 가 신 호 량 을 방출 한 후에 야 스 레 드 가 시작 되 어 실행 되 기 시작 했다.우 리 는 신 호 를 보 낼 때마다 스 레 드 를 하나 더 시작 할 것 이다.이 안의 논 리 는 이해 하기 어렵 지 않 을 것 이다.
총화
동시 다발 장면 에서 다 중 스 레 드 의 사용 은 몇 개의 스 레 드 를 더 시작 하여 서로 다른 임 무 를 하 는 것 이 아니 라 우 리 는 스 레 드 간 의 협력 이 필요 하 며 동기 화 되 고 그들의 상 태 를 얻 는 것 이 매우 쉽 지 않다.조심 하지 않 으 면 유령 버그 가 나타 나 고 숨 어 있 는 것 도 병발 문제 가 골 치 아 픈 주요 원인 이다.
이상 은 Python 감지 스 레 드 상 태 를 분석 하 는 솔 루 션 의 이벤트 와 신 호 량 에 대한 상세 한 내용 입 니 다.Python 감지 스 레 드 상태 이벤트 와 신 호 량 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
로마 숫자를 정수로 또는 그 반대로 변환그 중 하나는 로마 숫자를 정수로 변환하는 함수를 만드는 것이었고 두 번째는 그 반대를 수행하는 함수를 만드는 것이었습니다. 문자만 포함합니다'I', 'V', 'X', 'L', 'C', 'D', 'M' ; 문자열이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.