python 멀티 프로세스 병렬 제어 Semaphore와 호환 자물쇠 LOCK 구현

1. 자물쇠 이해


응용 장면 예시 설명: Lock 상호 배척 자물쇠: 예를 들어 C에 세 명의 동료가 동시에 화장실에 가야 하지만 화장실이 한 칸밖에 없다. 동료를 프로세스에 비유하고 여러 프로세스를 하고 하나의 화장실을 점령해야 한다. 우리는 순서를 우선시하고 하나씩 해야 한다. 그러면 반드시 직렬로 해야 한다. 선착순이다. 누군가가 사용하면 자물쇠를 채우고 끝난 후에 나머지는 계속 쟁탈해야 한다.

1. Lock으로 처리


세 명의 동료가 화장실을 점령하는 것을 모의하다

from multiprocessing import Process
from multiprocessing import Lock
import time
import random

def task1(p, lock):
    #  
    lock.acquire()
    print(f'{p}  ')
    time.sleep(random.randint(1, 3))
    print(f'{p}  ')
    #  
    lock.release()

def task2(p, lock):
    lock.acquire()
    print(f'{p}  ')
    time.sleep(random.randint(1, 3))
    print(f'{p}  ')
    lock.release()

def task3(p, lock):
    lock.acquire()
    print(f'{p}  ')
    time.sleep(random.randint(1, 3))
    print(f'{p}  ')
    lock.release()


if __name__ == '__main__':
    #  
    mutex = Lock()
    #  
    p1 = Process(target=task1, args=('task1', mutex,))
    p2 = Process(target=task2, args=('task2', mutex,))
    p3 = Process(target=task3, args=('task3', mutex,))

    p1.start()
    p2.start()
    p3.start()
실행 결과:
# 출력 결과: 세 프로세스가 서로 밀어내기 자물쇠를 쟁탈하기 시작한다. 먼저 빼앗은 것은 먼저 실행하고 실행이 끝난 후에 자물쇠를 풀고 나머지는 계속 쟁탈한다.
task1 배설 시작
task1 배설 종료
task2 배설 시작
task2 배설 종료
task3 배설 시작
task3 배설 종료
1. 참고:
  • 함수에 서로 밀어넣기,lock.acquire () 자물쇠를 한 번 잠그면lock입니다.release () 잠금 해제를 한 번 합니다. 잠금 해제와 잠금 해제 사이에 실행할 코드를 쓰십시오
  • 두 번 이상 자물쇠를 계속 잠그면 자물쇠가 사라지고 코드가 계속 실행되지 않습니다.자물쇠를 한 번 잠그고 한 번 풀어야 하는데..
  • 2, lock 및 join 비교:
  • 공통점----- 모두 병행을 직렬로 바꾸어 집행 순서를 보장할 수 있다
  • 차이점---join은 인위적으로 순서를 설정했고lock은 순서를 다투게 하여 공평성을 확보했다
  • 2. 반사를 이용하여 위의 코드를 최적화한다


    위의 코드는 선진적인 선출, 일진일출 효과가 있지만 완벽하지 않다.우리가 화장실에 가는 사람이 먼저 뺏고 먼저 올라가는 것은 코드에서 start () 순서에 따라 실행하는 것이 아니라는 것을 전반적으로 알고 있다.먼저 선점한 프로세스의 제한성이 더 합리적이어야 한다.
    
    from multiprocessing import Process
    from multiprocessing import Lock
    import time
    import random
    import sys
    
    def task1(p, lock):
        #  
        lock.acquire()
        print(f'{p}  ')
        time.sleep(random.randint(1, 3))
        print(f'{p}  ')
        #  
        lock.release()
    
    def task2(p, lock):
        lock.acquire()
        print(f'{p}  ')
        time.sleep(random.randint(1, 3))
        print(f'{p}  ')
        lock.release()
    
    def task3(p, lock):
        lock.acquire()
        print(f'{p}  ')
        time.sleep(random.randint(1, 3))
        print(f'{p}  ')
        lock.release()
    
    
    if __name__ == '__main__':
        slock = Lock()
        for i in range(1,4):
           p = Process(target=getattr(sys.modules[__name__], f'task{i}'), args=(f'task{i}', slock))
           p.start()
    출력 결과:
    task2 인쇄 시작
    task2 인쇄 종료
    task3 인쇄 시작
    task3 인쇄 종료
    task1 인쇄 시작
    task1 인쇄 종료

    2. 프로세스 병렬 제어 semaphore


    semaphore (신호량): 공유 자원에 대한 접근 수량을 제어하고 같은 시간에 동시에 보내는 프로세스 수를 제어할 수 있습니다
    신호량: 자물쇠이기도 하지만 데이터 안전성을 보장하지 않고 여러 개의 라인을 동시에 켜지만 동시에 동시에 실행하는 상한선, 뒤에서 얼마나 걷고 얼마나 들어가는지를 규정한다.(동시 수량 제어용)

    1. 다중 프로세스 제어 예 (1)

    
    #  : 5 , 5 , 20 , 5 , , 
    
    #  , 
    from threading import Semaphore, Thread, currentThread
    import time
    import random
    
    sem = Semaphore(3)             #  5
    
    def task():
        sem.acquire()
        print(f'{currentThread().name}')
        time.sleep(random.randint(1,3))
        sem.release()
    
    if __name__ == '__main__':
        for i in range(20):
            t = Thread(target=task)
            t.start()
    실행 결과: 첫 병발량은 3, 뒤에 자물쇠를 빼앗아 먼저 실행
    Thread-1
    Thread-2
    Thread-3
    Thread-4
    Thread-5
    Thread-6
    Thread-7
    Thread-8
    Process finished with exit code 0

    2. 다중 프로세스 제어 예 (2)

    
    import multiprocessing
    import time
    
    def worker(s, i):
        s.acquire()
        print(time.strftime('%Y-%m-%d %H:%M:%S'), multiprocessing.current_process().name + "  , ")
        time.sleep(i)
        print(time.strftime('%Y-%m-%d %H:%M:%S'), multiprocessing.current_process().name + "  , ")
        s.release()
    
    if __name__ == '__main__':
        s = multiprocessing.Semaphore(2)
        for i in range(8):
            p = multiprocessing.Process(target=worker, args=(s, 1))
            p.start()
    
    
    실행 결과:
    실행 결과 출력의 단말기에서 한 번 막힐 때마다 리턴 키를 누르면 프로세스의 병행 실행을 더욱 뚜렷하게 볼 수 있다.
    다음 실행 결과를 통해 알 수 있듯이 같은 시간에 두 개의 프로세스가 실행되고 있다
    2021-05-18 22:50:37 Process-1 선점 및 잠금 획득, 실행
    2021-05-18 22:50:37 Process-2 선점 및 잠금 획득, 실행
    2021-05-18 22:50:38 Process-1 실행 종료, 잠금 해제
    2021-05-18 22:50:38 Process-3 선점 및 잠금 획득, 실행
    2021-05-18 22:50:38 Process-2 실행 종료, 잠금 해제
    2021-05-18 22:50:38 Process-4 선점 및 잠금 획득, 실행
    2021-05-18 22:50:39 Process-3 실행 종료, 잠금 해제
    2021-05-18 22:50:39 Process-5 선점 및 잠금 획득, 실행
    2021-05-18 22:50:39 Process-4 실행 종료, 잠금 해제
    2021-05-18 22:50:39 Process-6 선점 및 잠금 획득, 실행
    2021-05-18 22:50:40 Process-5 실행 종료, 잠금 해제
    2021-05-18 22:50:40 Process-7 선점 및 잠금 획득, 실행
    2021-05-18 22:50:40 Process-6 실행 종료, 잠금 해제
    2021-05-18 22:50:40 Process-8 선점 및 잠금 획득, 실행
    2021-05-18 22:50:41 Process-7 실행 종료, 자물쇠 해제
    2021-05-18 22:50:41 Process-8 실행 종료, 잠금 해제
    Process finished with exit code 0

    3. 프로세스 동기화의 LOCK


    여러 프로세스가 동시에 실행되어 자원 이용률을 높이고 효율을 높일 수 있지만, 때로는 한 프로세스가 공유 자원에 접근할 수 있는 경우 자물쇠 LOCK을 사용해야 한다

    1. LOCK 제외의 예

    
    import multiprocessing
    import time
    
    def task1():
        n = 4
        while n > 1:
            print(f'{time.strftime("%Y-%M-%d %H:%M:%S")}  task1  ')
            time.sleep(1)
            n -= 1
    
    def task2():
        n = 4
        while n > 1:
            print(f'{time.strftime("%Y-%M-%d %H:%M:%S")}  task2  ')
            time.sleep(1)
            n -= 1
    
    def task3():
        n = 4
        while n > 1:
            print(f'{time.strftime("%Y-%M-%d %H:%M:%S")}  task3  ')
            time.sleep(1)
            n -= 1
    
    if __name__ == '__main__':
        p1 = multiprocessing.Process(target=task1)
        p2 = multiprocessing.Process(target=task2)
        p3 = multiprocessing.Process(target=task3)
        p1.start()
        p2.start()
        p3.start()
    
    
    실행 결과:
    2021-59-18 22:59:46 task1 출력 정보
    2021-59-18 22:59:46 task2 출력 정보
    2021-59-18 22:59:46 task3 출력 정보
    2021-59-18 22:59:47 task1 출력 정보
    2021-59-18 22:59:47 task2 출력 정보
    2021-59-18 22:59:47 task3 출력 정보
    2021-59-18 22:59:48 task1 출력 정보
    2021-59-18 22:59:48 task2 출력 정보
    2021-59-18 22:59:48 task3 출력 정보
    Process finished with exit code 0

    2. LOCK 예제 추가


    두 가지 자물쇠 추가 방식이 있습니다. 우선 lock = multiprocessing을 합니다.Lock() 잠금 객체 lock 생성
  • with lock: with는 실행하기 전에 lock을 시작하고 실행이 끝난 후에 lock을 닫습니다
  • lock.acquire() … lock.release (): 주의해라. 이 두 사람은 반드시 하나하나의 대응 관계이어야 한다
  • 
    import multiprocessing
    
    import time
    
    def task1(lock):
        with lock:
            n = 4
            while n > 1:
                print(f'{time.strftime("%Y-%M-%d %H:%M:%S")}  task1  ')
                time.sleep(1)
                n -= 1
    
    def task2(lock):
        lock.acquire()
        n = 4
        while n > 1:
            print(f'{time.strftime("%Y-%M-%d %H:%M:%S")}  task2  ')
            time.sleep(1)
            n -= 1
        lock.release()
    
    def task3(lock):
        lock.acquire()
        n = 4
        while n > 1:
            print(f'{time.strftime("%Y-%M-%d %H:%M:%S")}  task3  ')
            time.sleep(1)
            n -= 1
        lock.release()
    
    if __name__ == '__main__':
        lock = multiprocessing.Lock()
        p1 = multiprocessing.Process(target=task1, args=(lock,))
        p2 = multiprocessing.Process(target=task2, args=(lock,))
        p3 = multiprocessing.Process(target=task3, args=(lock,))
        p1.start()
        p2.start()
        p3.start()
    실행 결과
    2021-11-18 23:11:37task1 출력 정보
    2021-11-18 23:11:38task1 출력 정보
    2021-11-18 23:11:39task1 출력 정보
    2021-11-18 23:11:40task2 출력 정보
    2021-11-18 23:11:41task2 출력 정보
    2021-11-18 23:11:42task2 출력 정보
    2021-11-18 23:11:43 task3 출력 정보
    2021-11-18 23:11:44 task3 출력 정보
    2021-11-18 23:11:45task3 출력 정보
    Process finished with exit code 0
     
    이것은python이 다중 프로세스를 실현하고 제어하는 Semaphore와 상호 차단 LOCK에 관한 글을 소개합니다. 더 많은 관련python 다중 프로세스 Semaphore와 LOCK 내용은 저희 이전의 글을 검색하거나 아래의 관련 글을 계속 훑어보십시오. 앞으로 많은 응원 부탁드립니다!

    좋은 웹페이지 즐겨찾기