> 백엔드 개발 > 파이썬 튜토리얼 > Python 다중 스레드 프로그래밍 4: 교착 상태 및 재진입 잠금

Python 다중 스레드 프로그래밍 4: 교착 상태 및 재진입 잠금

高洛峰
풀어 주다: 2016-10-18 11:31:53
원래의
1415명이 탐색했습니다.

Deadlock

스레드 간에 여러 리소스를 공유할 때 두 스레드가 각각 리소스의 일부를 점유하면서 동시에 서로의 리소스를 기다리면 교착 상태가 발생합니다. 교착 상태는 거의 발생하지 않지만 발생하면 응용 프로그램의 응답이 중지될 수 있습니다. 교착 상태의 예를 살펴보겠습니다.

# encoding: UTF-8
import threading
import time
  
class MyThread(threading.Thread):
    def do1(self):
        global resA, resB
        if mutexA.acquire():
             msg = self.name+' got resA'
             print msg
               
             if mutexB.acquire(1):
                 msg = self.name+' got resB'
                 print msg
                 mutexB.release()
             mutexA.release()
    def do2(self):
        global resA, resB
        if mutexB.acquire():
             msg = self.name+' got resB'
             print msg
               
             if mutexA.acquire(1):
                 msg = self.name+' got resA'
                 print msg
                 mutexA.release()
             mutexB.release()
   
      
    def run(self):
        self.do1()
        self.do2()
resA = 0
resB = 0
  
mutexA = threading.Lock()
mutexB = threading.Lock()
  
def test():
    for i in range(5):
        t = MyThread()
        t.start()
if __name__ == '__main__':
    test()
로그인 후 복사

실행 결과:


Thread-1 got resA

Thread-1 got resB

Thread-1이 resB를 얻었습니다

Thread-1이 resA를 얻었습니다

Thread-2가 resA를 얻었습니다

Thread-2가 resB를 얻었습니다

Thread-2가 resB를 얻었습니다

Thread-2가 resA를 얻었습니다

Thread-3이 resA를 얻었습니다

Thread-3이 resB를 얻었습니다

Thread-3이 resB를 얻었습니다

Thread-3에 resA가 있음

Thread-5에 resA가 있음

Thread-5에 resB가 있음

Thread-5에 resB가 있음

Thread-4가 resA를 얻었습니다


현재 프로세스가 종료되었습니다.


재진입 잠금

더 단순한 교착 상태 상황은 스레드가 동일한 리소스를 요청하기 위해 "반복"하여 교착 상태가 직접적으로 발생하는 경우입니다.

import threading
import time
  
class MyThread(threading.Thread):
    def run(self):
        global num
        time.sleep(1)
  
        if mutex.acquire(1): 
            num = num+1
            msg = self.name+' set num to '+str(num)
            print msg
            mutex.acquire()
            mutex.release()
            mutex.release()
num = 0
mutex = threading.Lock()
def test():
    for i in range(5):
        t = MyThread()
        t.start()
if __name__ == '__main__':
    test()
로그인 후 복사

동일한 스레드에서 동일한 리소스에 대한 여러 요청을 지원하기 위해 Python은 "재진입 잠금"인 threading.RLock을 제공합니다. RLock은 내부적으로 Lock과 카운터 변수를 유지하며, 카운터는 획득 횟수를 기록하므로 리소스가 여러 번 필요할 수 있습니다. 스레드의 모든 획득이 해제될 때까지 다른 스레드가 리소스를 얻을 수 있습니다. 위의 예에서 Lock 대신 RLock을 사용하면 교착 상태가 발생하지 않습니다.

import threading
import time
  
class MyThread(threading.Thread):
    def run(self):
        global num
        time.sleep(1)
  
        if mutex.acquire(1): 
            num = num+1
            msg = self.name+' set num to '+str(num)
            print msg
            mutex.acquire()
            mutex.release()
            mutex.release()
num = 0
mutex = threading.RLock()
def test():
    for i in range(5):
        t = MyThread()
        t.start()
if __name__ == '__main__':
    test()
로그인 후 복사

실행 결과:


Thread-1 set num 1로

Thread-3은 num을 2로 설정

Thread-2는 num을 3으로 설정

Thread-5는 num을 4로 설정

Thread-4 숫자를 5로 설정


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿