ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • IOCP(2)
    개발/C·C++ 2021. 6. 4. 11:20

    >> 번역글입니다

    >> 의역은 있고 오역이 있을 수 있습니다

    >> 출처 https://docs.microsoft.com/en-us/windows/win32/fileio/i-o-completion-ports

    >> IOCP(1)에서 이어집니다

     

    스레드는 입출력 완료 포트의 큐에 완료 패킷을 넣기 위해 PostQueuedCompletionStatus 함수를 사용할 수 있습니다. 이렇게 하면, 완료 포트는 입출력 시스템에서 입출력 완료 패킷을 받는 것뿐만 아니라 다른 프로세스 스레드의 연락을 수신하는 것에도 사용될 수 있습니다. PostQueuedCompletionStatus 함수는 하나의 비동기 입출력 작업을 시작하지 않고도, 어플리케이션이 입출력 완료 포트에 자신만의 완료 패킷을 대기하게 할 수 있습니다. 외부 이벤트의 워커 스레드에게 알려야 할 때 유용하게 사용할 수 있습니다.

     

    입출력 완료 포트 핸들과 모든 파일 핸들은 입출력 완료 포트에 대한 참조라고 할 수 있는 특정한 입출력 완료 포트에 연결됩니다. 입출력 완료 포트는 더 이상 참조되지 않을 때 해제됩니다. 그러므로 모든 핸들은 입출력 완료 포트 그리고 연결된 시스템 리소스를 해제하기 위해 반드시 적절하게 종료되어야 합니다. 이 조건이 충족된 후에, 어플리케이션은 CloseHandle 함수를 호출해 입출력 완료 포트를 닫아야 합니다.

     

    Note
    하나의 입출력 완료 포트는 이를 생성한 프로세스와 연결되고 프로세스 간에 공유되지 않습니다. 하지만 핸들은 같은 프로세스 안에 있는 여러 스레들 사이가 공유할 수 있습니다.

     

    Threads and Concurrency

    입출력 완료 포트에서 신중하게 고려해야 할 가장 중요한 특성은 동시성 값(concurrency value)입니다. 완료 포트의 동시성 변수는 NumberOfConcurrentThreads를 파라미터로 받아 CreateIoCompletionPort 함수로 생성될 때 정해집니다. 이 변수는 완료 포트와 연결되어 작동할 수 있는 스레드의 개수를 제한합니다. 완료 포트와 연결된 실행 가능한 스레드의 총 개수가 동시성 값에 도달하면, 시스템은 사용할 수 있는 스레드 개수가 동시성 값 밑으로 떨어지기 전까지, 포트와 연결된 다음 스레드의 실행을 차단합니다.

     

    가장 효율적인 시나리오는 포트가 동시성 한계에 도달해서 대기 상태가 충족되지 않을 때가 아니라, 큐에서 완료 패킷이 대기하고 있을 때입니다. GetQueuedCompletionStatus 함수 호출에 대기하고 있는, 하나 혹은 여러 스레드의 동시성 변수에 무슨 일이 일어나는지 생각해봐야 합니다. 이 경우, 작업 중인 스레드가 GetQueuedCompletionStatus를 호출했을 때 큐가 대기 중인 완료 패킷을 항상 가지고 있다면 앞서 말한 것처럼, 스레드 큐는 LIFO이기 때문에 실행을 차단하지 지 않을 것입니다. 대신에 이 스레드는 큐에 있는 다음 완료 패킷을 바로 가져올 것입니다. 실행 중인 스레드가 연속적으로 완료 패킷을 꺼내고 다른 스레드는 실행될 수 없기 때문에 스레드 컨텍스트 전환이 일어나지 않습니다.

     

    Note
    이전 예시에서 여분의 스레드는 쓸모 없고 실행되지 않을 것처럼 보이지만, 실행 중인 스레드가 다른 메커니즘 때문에 대기 상태가 되지 않거나, 종료되거나, 연결된 입출력 포트가 닫히지 않는다고 가정합니다. 어플리케이션을 설계할 때 스레드 실행으로 생기는 모든 영향을 고려하십시오.

     

    동시성 값으로 선택할 수 있는 가장 적절한 최대 값은 CPU의 개수입니다. 트랙잭션에 긴 연산이 필요하면, 동시성 값이 클수록 더 많은 스레드를 실행할 수 있습니다. 각 완료 패킷은 완료하는데 더 오랜 시간이 걸릴 수 있지만, 동시에 더 많은 완료 패킷이 처리될 것입니다. 프로파일링 도구를 사용하여 동시성 값을 테스트해보면서 어플리케이션에 대한 최상의 효과를 얻을 수 있습니다.

     

    시스템은 동일한 입출력 완료 포트와 연결되어 있고 실행 중인 다른 스레드가 SuspendThread 함수 호출 등과 같은 이유로 대가 상태인 경우, GetQueuedCompletionStatus 함수에서 대기 중인 스레드가 완료 패킷을 처리하도록 합니다. 대기하고 있던 스레드가 다시 실행되면 활성된 스레드의 수가 동시성 값을 초과하는 짧은 기간이 있을 수 있습니다. 시스템은 황성 스레드 수가 동시성 값 아래로 떨어질 때까지 어떤 새로운 활성 스레드도 허용하지 하지 않는 방법으로 스레드 수를 줄입니다. 이것이 어플리케이션이 동시성 값보다 스레드 풀에 더 많은 스레드를 생성해야 하는 이유 중 하나입니다. 스레드 풀 관리는 이 주제를 벗어나지만 경험 상 좋은 방법은 시스템의 프로세서보다 스레드 풀에 최소 두 배의 스레드를 가지는 것입니다. 스레드 풀링에 관해 더 알고 싶다면 스레드 풀을 참고하세요.

     

    Supported I/O Functions

     

    '개발 > C·C++' 카테고리의 다른 글

    timeBeginPeriod function  (0) 2021.06.10
    WSASend function  (0) 2021.06.06
    [Design Pattern] Observer  (0) 2021.05.30
    [Pointer] 정수형을 문자형으로  (0) 2021.05.28
    IOCP(1)  (0) 2021.05.25

    댓글

Designed by Tistory.