복붙노트

[PYTHON] 파이썬에서 스레딩하기 [닫힘]

PYTHON

파이썬에서 스레딩하기 [닫힘]

파이썬에서 멀티 스레드 응용 프로그램을 작성하는 데 사용되는 모듈은 무엇입니까? 저는이 언어와 Stackless Python이 제공하는 기본적인 동시성 메커니즘을 알고 있습니다 만, 각각의 강점과 약점은 무엇입니까?

해결법

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

    1.복잡성이 증가하는 순서로 :

    복잡성이 증가하는 순서로 :

    장점 :

    단점 :

    간단한 유스 케이스에서는 각 스레드가 자체 스레드가 아닌 자체 프로세스에서 실행된다는 점을 제외하고는 스레딩 사용과 똑같은 것처럼 보입니다. (글자 그대로 : 엘리의 예를 들고 스레딩을 다중 처리, 스레드, 프로세스 및 대기열 (모듈)과 다중 처리로 바꾸면 .Queue는 정상적으로 실행되어야합니다.)

    장점 :

    단점 :

    장점 :

    단점 :

    모든 경우에 나는 당신이 이미 멀티 태스킹과 관련된 많은 문제, 특히 태스크간에 데이터를 공유하는 방법의 까다로운 문제를 이미 알고 있다고 가정하고 있습니다. 어떤 이유로 잠금 장치 및 조건을 사용하는시기와 방법을 알지 못하는 경우이를 시작해야합니다. 멀티 태스킹 코드는 미묘한 부분들로 구성되어 있으며 시작하기 전에 개념을 잘 이해하는 것이 가장 좋습니다.

  2. ==============================

    2."가짜 스레드"에서부터 외부 프레임 워크에 이르기까지 이미 다양한 답변을 얻었지만 CPython 스레딩의 "비밀 소스"인 Queue.Queue는 언급하지 않았습니다.

    "가짜 스레드"에서부터 외부 프레임 워크에 이르기까지 이미 다양한 답변을 얻었지만 CPython 스레딩의 "비밀 소스"인 Queue.Queue는 언급하지 않았습니다.

    확장하려면 : 순수 파이썬 CPU가 많은 프로세싱을 오버랩 할 필요가없는 한 (멀티 프로세싱이 필요하지만 자체적 인 큐 구현이 포함되어 있으므로 일반적인주의 사항을 적용 할 수 있습니다. 파이썬의 빌트인 스레딩은 할 것이다.하지만 다음과 같이 조언하면된다.

    공유 메모리, 아마도 스레딩 대 멀티 프로세싱의 주요한 장점을 잊어 버렸습니다. 잘 작동하지 않으며, 확장 성이 좋지 않으며, 절대로 존재하지 않으며, 절대 존재하지 않습니다. 하위 스레드를 생성하고 나중에 변경하지 않기 전에 한 번 설정된 데이터 구조에만 공유 메모리를 사용하십시오. 다른 모든 경우에는 단일 스레드가 해당 자원을 담당하고 Queue를 통해 해당 스레드와 통신하십시오.

    가변적 인 데이터 구조 또는 그 응집력 그룹, 외부 프로세스 (DB, XMLRPC 서버 등)에 대한 연결, 외부 파일 등등, 잠금으로 보호하려는 모든 리소스에 특수 스레드를 사용하십시오. 그 종류의 전용 리소스가 없거나 필요없는 일반 목적의 작업을 수행하는 작은 스레드 풀을 가져 오십시오. 필요에 따라 스레드를 생성하거나 스레드 전환 오버 헤드가 당신을 압도 할 것입니다.

    두 스레드 사이의 통신은 항상 Queue.Queue를 통해 이루어집니다 - 메시지 전달의 한 형태, 멀티 프로세싱을위한 유일한 제정신의 토대 (트랜잭션 메모리 외에도 유망하지만 하스켈을 제외한 생산에 가치있는 구현은 아는 바입니다).

    단일 리소스 (또는 일관된 리소스 세트)를 관리하는 각 전용 스레드는 특정 Queue.Queue 인스턴스에 대한 요청을 수신 대기합니다. 풀의 스레드는 하나의 공유 Queue.Queue에서 대기합니다 (큐는 견고하게 스레드 안전하며 이로 인해 실패하지 않습니다).

    일부 대기열 (공유 또는 전용)에서 요청을 대기열에 올려야하는 스레드는 결과를 기다리지 않고 수행하고 계속 진행합니다. 스레드는 결국 Queue.Queue의 인스턴스와 쌍 (요청, 수신 대기)을 요청 큐에 대한 결과 또는 확인이 필요하며, 결국 응답 또는 확인이 진행하기 위해 필수적 일 때, )를받습니다. 실제 응답이나 확인뿐만 아니라 오류 응답을받을 준비가되었는지 확인하십시오 (Twisted의 지연은 이러한 종류의 구조화 응답을 구성하는 데 유용합니다, BTW!).

    큐를 사용하여 한 스레드에서 사용할 수 있지만 한 번에 여러 스레드간에 공유 할 수없는 리소스 인스턴스를 "파킹"할 수 있습니다 (일부 DBAPI 구성 요소와의 DB 연결, 다른 리소스와의 커서 연결 등). 더 많은 풀링을위한 전용 스레드 요구 사항 (공유 대기열에서 대기열 가능 자원을 필요로하는 풀 스레드는 적절한 대기열에서 자원을 가져오고 필요한 경우 대기 등).

    Twisted는 지연된 덕분이 아니라 견고하고 확장 성이 뛰어난 기본 아키텍처로 인해이 미뉴에이트 (또는 경우에 따라 스퀘어 댄스)를 구성하는 좋은 방법입니다. 스레드 나 하위 프로세스를 사용할 때만 정렬 할 수 있습니다. 정말로 보장되는 반면, 일반적으로 단일 이벤트 중심 스레드에서 스레드 가치있는 것으로 간주되는 대부분의 작업을 수행합니다.

    하지만, 나는 Twisted가 모든 사람들을위한 것이 아니라는 것을 깨닫습니다. "자원을 낭비하거나 낭비하지 마라. 대기열을 대기열에 넣고, 잠금 장치가 필요하지 않게하거나, Guido가 금지하고, 세마포어 나 조건과 같은 모든 동기화 절차를 접근 할 수 있습니다. 비동기식 이벤트 기반 방법론에 대한 귀하의 머리를 감쌀 수 없을지라도 여전히 사용됩니다. 그리고 지금까지 발견하지 못한 다른 널리 쓰이는 스레딩 방식보다 더 높은 신뢰성과 성능을 제공 할 것입니다.

  3. ==============================

    3.그것은 당신이 무엇을하려고하는지에 달려 있지만, 표준 라이브러리에서 스레딩 모듈을 사용하는 것이 부분적입니다. 왜냐하면 어떤 기능을 사용하기 쉽고 별도의 스레드에서 실행하기가 쉽기 때문입니다.

    그것은 당신이 무엇을하려고하는지에 달려 있지만, 표준 라이브러리에서 스레딩 모듈을 사용하는 것이 부분적입니다. 왜냐하면 어떤 기능을 사용하기 쉽고 별도의 스레드에서 실행하기가 쉽기 때문입니다.

    from threading import Thread
    
    def f():
        ...
    
    def g(arg1, arg2, arg3=None):
        ....
    
    Thread(target=f).start()
    Thread(target=g, args=[5, 6], kwargs={"arg3": 12}).start()
    

    등등. Queue 모듈에서 제공하는 동기화 된 대기열을 사용하는 제작자 / 사용자 설정이있는 경우가 종종 있습니다.

    from Queue import Queue
    from threading import Thread
    
    q = Queue()
    def consumer():
        while True:
            print sum(q.get())
    
    def producer(data_source):
        for line in data_source:
            q.put( map(int, line.split()) )
    
    Thread(target=producer, args=[SOME_INPUT_FILE_OR_SOMETHING]).start()
    for i in range(10):
        Thread(target=consumer).start()
    
  4. ==============================

    4.Kamaelia는 많은 의사 소통 프로세스로 응용 프로그램을 작성하기위한 Python 프레임 워크입니다.

    Kamaelia는 많은 의사 소통 프로세스로 응용 프로그램을 작성하기위한 Python 프레임 워크입니다.

    Kamaelia로 쉬운 동시성 - 파트 1 (59:08) Kamaelia로 쉬운 동시성 - 제 2 부 (18:15)

  5. ==============================

    5.Kamaelia에 관해서는, 위의 대답은 실제로 여기의 이익을 다루지 않습니다. Kamaelia의 접근 방식은 동시성을위한 단일 시스템에서 스레드, 생성자 및 프로세스를 처리하기 위해 완벽하지는 않은 실용적인 통합 인터페이스를 제공합니다.

    Kamaelia에 관해서는, 위의 대답은 실제로 여기의 이익을 다루지 않습니다. Kamaelia의 접근 방식은 동시성을위한 단일 시스템에서 스레드, 생성자 및 프로세스를 처리하기 위해 완벽하지는 않은 실용적인 통합 인터페이스를 제공합니다.

    근본적으로 이것은받은 편지함과 보낼 편지함이있는 실행중인 물건의 은유를 제공합니다. 보낼 편지함으로 메시지를 보내면 함께 묶어지면 메시지가 보낼 편지함에서받은 편지함으로 이동합니다. 이 메타포 / API는 생성자, 스레드 또는 프로세스를 사용하든 다른 시스템과 대화를 나누 든 관계없이 동일하게 유지됩니다.

    "완벽하지는 않은"부분은 구문 상 설탕이 아직받은 편지함과 보낼 편지함에 추가되지 않아서 발생합니다 (토론 중이지만). 시스템의 안전성 / 유용성에 중점을 둡니다.

    생산자 소비자 예제를 위에서 베어 스레딩을 사용하여 살펴보면 Kamaelia에서 다음과 같이됩니다.

    Pipeline(Producer(), Consumer() )
    

    이 예에서는 스레드 된 구성 요소 또는 기타 구성 요소인지 여부는 중요하지 않지만 유일한 차이점은 사용 관점에서 볼 때 구성 요소의 기본 클래스입니다. 생성기 구성 요소는 목록, Queue.Queues를 사용하여 스레드 된 구성 요소 및 os.pipes를 사용하여 프로세스를 사용하여 통신합니다.

    이 접근법의 배경은 버그를 디버그하기가 더 어려워 지도록 만드는 것입니다. 스레딩 (threading) 또는 공유 메모리 동시성 (concurrency)에서, 가장 큰 문제는 실수로 공유 데이터 업데이트가 끊어진 것입니다. 메시지 전달을 사용하면 한 클래스의 버그를 제거 할 수 있습니다.

    베어 스레딩 (bare threading)을 사용하고 어디에서나 잠금을 사용한다면 일반적으로 코드를 작성할 때 실수를하지 않을 것이라는 가정하에 작업하고있는 것입니다. 우리 모두는 그 일을 열망하지만, 매우 드문 경우입니다. 잠금 동작을 한 곳에서 마무리하면 상황이 잘못 될 수있는 곳을 단순화합니다. (컨텍스트 핸들러는 도움을 주지만 컨텍스트 핸들러 외부의 우발적 인 업데이트에는 도움이되지 않습니다)

    분명히 모든 코드 조각이 메시지 전달 및 공유 스타일로 쓰여질 수는 없으므로 Kamaelia에는 단순한 소프트웨어 트랜잭션 메모리 (STM)가 있습니다. 이것은 STM (소프트웨어 트랜잭션 메모리)입니다.이 코드는 변수 이름에 대한 버전 제어와 비슷합니다. 일부 변수를 체크 아웃하고 업데이트하고 다시 커밋하십시오. 충돌이 생기면 씻어 내고 반복하십시오.

    관련 링크 :

    어쨌든 유용한 답이되기를 바랍니다. FWIW, Kamaelia 설치의 핵심 이유는 개를 흔들지 않고도 Python 시스템에서 동시성을보다 안전하고 사용하기 쉽도록 만드는 것입니다. (즉, 구성 요소의 큰 물통

    나는 Kamaelia의 다른 대답이 왜 수정되었는지 이해할 수 있습니다. 심지어 나에게도 대답보다는 광고처럼 보입니다. Kamaelia의 저자로서 이것이 좀 더 관련성이 높은 콘텐츠를 포함하기를 희망하지만 열의를 보니 좋았습니다 :-)

    그리고 그것은 저의 말입니다.이 대답은 정의에 의해 편향되어 있다는 경고를 받으십시오. 그러나 저로서는 Kamaelia의 목표는 IMO 모범 사례가 무엇인지 시험하고 포장하는 것입니다. 몇 가지 시스템을 시험해보고 어떤 것이 효과가 있는지 알아볼 것을 제안합니다. (스택 오버플로에 대해 부적절한 경우에도, 죄송합니다 -이 포럼에 처음 온 :-)

  6. ==============================

    6.스레드를 전혀 사용하지 않으면 Stackless Python의 Microthreads (Tasklets)를 사용할 것입니다.

    스레드를 전혀 사용하지 않으면 Stackless Python의 Microthreads (Tasklets)를 사용할 것입니다.

    전체 온라인 게임 (대량 멀티 플레이어)은 Stackless 및 멀티 스레딩 원리를 기반으로합니다. 원래는 게임의 대규모 멀티 플레이어 속성 때문에 느려지 기 때문입니다.

    CPython의 스레드는 널리 사용되지 않습니다. 한 가지 이유는 실행의 많은 부분에 대한 스레딩을 직렬화하는 전역 인터프리터 잠금 인 GIL입니다. 필자의 경험은 이러한 방식으로 빠른 응용 프로그램을 만드는 것이 정말 어렵다는 것입니다. 필자의 예제에서는 모든 코어가 스레딩과 함께 느려지는 곳 (하나의 코어를 사용하지만 많은 경우 입력을 기다려야 성능 향상이 가능할 것입니다).

    Cython에서는 가능한 경우 별도의 프로세스를 사용하십시오.

  7. ==============================

    7.정말로 손을 더럽 히고 싶다면 발전기를 사용하여 코 루틴을 가짜로 만들 수 있습니다. 그것은 아마도 관련 업무 측면에서 가장 효율적은 아니지만 코 루틴은 다른 곳에서 찾을 수있는 선제 멀티 태스킹보다는 협동 멀티 태스킹에 대한 훌륭한 제어 기능을 제공합니다.

    정말로 손을 더럽 히고 싶다면 발전기를 사용하여 코 루틴을 가짜로 만들 수 있습니다. 그것은 아마도 관련 업무 측면에서 가장 효율적은 아니지만 코 루틴은 다른 곳에서 찾을 수있는 선제 멀티 태스킹보다는 협동 멀티 태스킹에 대한 훌륭한 제어 기능을 제공합니다.

    하나의 장점은 협업 멀티 태스킹을 사용할 때 전체적으로 잠금 또는 뮤텍스가 필요하지 않지만 더 중요한 이점은 "스레드"간에 거의 제로의 스위칭 속도입니다. 물론, 스택리스 파이썬 (Stackless Python)은 그 점에도 매우 좋습니다. 파이썬 일 필요가 없다면 Erlang이있다.

    아마도 협업 멀티 태스킹에서 가장 큰 단점은 입출력 차단에 대한 일반적인 해결 방법이 없다는 것입니다. 또한 위조 된 동시 루틴에서는 스레드 내에서 스택의 최상위 레벨이 아닌 "스레드"를 전환 할 수 없다는 문제가 발생합니다.

    가짜 코 루틴을 사용하여 약간 복잡한 애플리케이션을 작성한 후에는 OS 레벨에서 프로세스 스케줄링 작업을 실제로 이해하게 될 것입니다.

  8. from https://stackoverflow.com/questions/1190206/threading-in-python by cc-by-sa and MIT license