복붙노트

[PYTHON] 파이썬에서 multiprocessing.pool으로 전역 잠금 / 세마포어를 만드는 법?

PYTHON

파이썬에서 multiprocessing.pool으로 전역 잠금 / 세마포어를 만드는 법?

자식 프로세스에서 리소스 액세스를 제한하고 싶습니다. 예를 들어 - HTTP 다운로드, 디스크 io 등을 제한하십시오.이 기본 코드를 어떻게 확장 할 수 있습니까?

몇 가지 기본적인 코드 예제를 공유하십시오.

pool = multiprocessing.Pool(multiprocessing.cpu_count())
while job_queue.is_jobs_for_processing():
  for job in job_queue.pull_jobs_for_processing:
    pool.apply_async(do_job, callback = callback)
pool.close()
pool.join()

해결법

  1. ==============================

    1.모든 하위 프로세스에서 전역을 정의 할 수 있도록 풀을 만들 때 initializer 및 initargs 인수를 사용하십시오.

    모든 하위 프로세스에서 전역을 정의 할 수 있도록 풀을 만들 때 initializer 및 initargs 인수를 사용하십시오.

    예를 들면 :

    from multiprocessing import Pool, Lock
    from time import sleep
    
    def do_job(i):
        "The greater i is, the shorter the function waits before returning."
        with lock:
            sleep(1-(i/10.))
            return i
    
    def init_child(lock_):
        global lock
        lock = lock_
    
    def main():
        lock = Lock()
        poolsize = 4
        with Pool(poolsize, initializer=init_child, initargs=(lock,)) as pool:
            results = pool.imap_unordered(do_job, range(poolsize))
            print(list(results))
    
    if __name__ == "__main__":
        main()
    

    이 코드는 자물쇠를 사용하기 때문에 번호 0-3을 오름차순 (작업이 제출 된 순서)으로 인쇄합니다. with lock : 행을 주석 처리하여 내림차순으로 번호를 인쇄하십시오.

    이 솔루션은 Windows 및 Unix에서 모두 작동합니다. 그러나 프로세스가 유닉스 시스템에서 fork 할 수 있기 때문에 유닉스는 모듈 범위에서 전역 변수 만 선언하면된다. 자식 프로세스는 여전히 작동하는 잠금 객체를 포함하는 부모 메모리의 복사본을 가져옵니다. 따라서 이니셜 라이저는 꼭 필요한 것은 아니지만 코드가 작동하는 방법을 문서화하는 데 도움이 될 수 있습니다. 다중 처리가 분기를 통해 프로세스를 생성 할 수 있으면 다음과 같은 작업도 가능합니다.

    from multiprocessing import Pool, Lock
    from time import sleep
    
    lock = Lock()
    
    def do_job(i):
        "The greater i is, the shorter the function waits before returning."
        with lock:
            sleep(1-(i/10.))
            return i
    
    def main():
        poolsize = 4
        with Pool(poolsize) as pool:
            results = pool.imap_unordered(do_job, range(poolsize))
            print(list(results))
    
    if __name__ == "__main__":
        main()
    
  2. ==============================

    2.전역 세마포어를 사용하고 리소스에 액세스하는 경우이를 확인하십시오. 예 :

    전역 세마포어를 사용하고 리소스에 액세스하는 경우이를 확인하십시오. 예 :

    import multiprocessing
    from time import sleep
    
    semaphore = multiprocessing.Semaphore(2)
    
    def do_job(id):
        with semaphore:
            sleep(1)
        print("Finished job")
    
    def main():
        pool = multiprocessing.Pool(6)
        for job_id in range(6):
            print("Starting job")
            pool.apply_async(do_job, [job_id])
        pool.close()
        pool.join()
    
    if __name__ == "__main__":
        main()
    

    이 프로그램은 다른 스레드가 세마포를 기다리고 있기 때문에 초당 두 개의 작업 만 완료합니다.

  3. from https://stackoverflow.com/questions/28664720/how-to-create-global-lock-semaphore-with-multiprocessing-pool-in-python by cc-by-sa and MIT license