I/O Completion Ports

1.def

비동기 I/O Ports,,. 보다 저레벨의 I/O 입출력 핸들링 방법

2.description


I/O completion ports are used with asynchronous I/O. The CreateIoCompletionPort function associates an I/O completion port with one or more file handles. When an asynchronous I/O operation started on a file handle associated with a completion port is completed, an I/O completion packet is queued to the port. This can be used to combine the synchronization point for multiple file handles into a single object.

{{|
IOCP는 비동기 I/O로 쓰인다. 이는 CreateIoCompletionPort 함수를 통해 하나 또는 다수의 파일핸들에 연결된다. Completion Port작업이
완료시에 비동기 I/O가 작동하며 이에 I/O Completion packet이 큐에 넣어진다. IOCP는 하나의 Object에 대한 다수의 파일 핸들을 동기화
시키는 데 사용한다.
|}}

A thread uses the GetQueuedCompletionStatus function to wait for a completion packet to be queued to the completion port, rather than waiting directly for the asynchronous I/O to complete. Threads that block their execution on a completion port are released in last-in-first-out (LIFO) order. This means that when a completion packet is queued to the completion port, the system releases the last thread to block its execution on the port.

{{|
쓰레드는 GetQueuedCompletionStatus 함수를 통해 패킷이 포트에 들어오기 까지 Wait 된다. 이는 비동기 I/O를 위해 직접 쓰레드를 Wait하는
것 보다 낫다. 쓰레드의 실행이 블럭되고 이는 LIFO순서로 릴리즈 된다.(리쥼된다는말!)
|}}

When a thread calls GetQueuedCompletionStatus, it is associated with the specified completion port until it exits, specifies a different completion port, or frees the completion port. A thread can be associated with at most one completion port.
{{|
쓰레드가 GetQueuedCompletionStatus를 호출 할때, 쓰레드가 종료되기 전까지 그 특정 포트는 쓰레드에 연결 되어 있다. 다른 Completion Port를 쓰던가 또는 그
Completion Port 를 Free하던가..... 쓰레드는 최대 하나의 CompletionPort에 연결 된다.
|}}

The most important property of a completion port is the concurrency value. The concurrency value of a completion port is specified when the completion port is created. This value limits the number of runnable threads associated with the completion port. When the total number of runnable threads associated with the completion port reaches the concurrency value, the system blocks the execution of any subsequent threads that specify the completion port until the number of runnable threads associated with the completion port drops below the concurrency value. The most efficient scenario occurs when there are completion packets waiting in the queue, but no waits can be satisfied because the port has reached its concurrency limit. In this case, when a running thread calls GetQueuedCompletionStatus, it will immediately pick up the queued completion packet. No context switches will occur, because the running thread is continually picking up completion packets and the other threads are unable to run.

{{|
Completion Port의 가장 중요점은 동시에 쓰이는 값에 있다. Completion Port의 동시성은 포트가 생성될때 지정한다. 이 값은 Completion Port와 연결된 동작중인 쓰레드 수와
연관이 있으며, 총 동작중인 또 Completion Port와 연결된 쓰레드 수는 the concurrency value에 적용된다. ... 해석 NO ... 가장 효과적인 방법은 패킷이 queue에 들어오는
데로 쓰레드가 그 패킷을 가져오며 쓰레드가 동작중에 GetQueuedCompletionStatus를 호출해서 즉시 패킷을 가져오는 것이다. 문맥전환이 없고 계속적적으로 다른 쓰레드는 접근하
지 못하게 하고 하나의 쓰레드가 패킷을 얻어오는 것이다.
|}}

The best value to pick for the concurrency value is the number of CPUs on the machine. If your transaction required a lengthy computation, a larger concurrency value will allow more threads to run. Each transaction will take longer to complete, but more transactions will be processed at the same time. It is easy to experiment with the concurrency value to achieve the best effect for your application.

{{|
가장 최적의 concurrency value는 CPU의 수에 관계된 것으로 (내가 알기로는 2*CPU수 + 2) 또는 "+1"의 쓰레드가 적당한 것으로 알고 있다.
|}}

The PostQueuedCompletionStatus function allows an application to queue its own special-purpose I/O completion packets to the completion port without starting an asynchronous I/O operation. This is useful for notifying worker threads of external events.

{{|
PostQueuedCompletionStatus 함수는 어플리케이션이 비동기 I/O 명령어의 시작없이 자신의 특별한 목적의 I/O Completion 패킷을 가져오는 것을 허락한다.
이는 외부의 이벤트에 대해 쓰레드를 깨워(?:단순 notify)주는데 유용하다.
|}}

The completion port is freed when there are no more references to it. The completion port handle and every file handle associated with the completion port reference the completion port. All the handles must be closed to free the completion port. To close the port handle, call the CloseHandle function.

{{|
Completion Port는 더 이상 참조가 없을 때 놓아지며 , 놓을 때에는 꼭 CloseHandle 함수를 불러라.
|}}

From MSDN

{{|
IOCP를 쓰는 이유
소켓의 경우 패킷이 들어오면 Opertiong System의 Buffer에 우선 쓰여지고 버퍼의 데이타가 일정치 쌓이면 이를 어플리케이션 버퍼에 Copy 한
다음 어플리케이션에 Receieve 메세지를 날려준다. 이는 쓸 데없이 버퍼의 값을 두번 쓰게 만드는 작업을 낳는다. 보다 속도를 향상 시키기 위해
어플리케이션과 Operationg System이 같은 버퍼의 메모리 위치를 참조하게 만드는 것이 IOCP이다.
파일 전송이나 지속적 연결 상태에서 연속적인 데이타를 보내주는 데 쓰이며 I/O 핸들에 Socket 핸들을 넣어준다는 것 외에 그렇게 어렵지 않다.
익혀두면 후에 보다 쉽게 네트워크 프로그램을 할 수 있을 것이다.
|}}
From fnwinter and Devipa

3.using

소스가 너무 길어서 올리기 힘드오. example을 보시오!

4.example

5.function

~cpp CreateIoCompletionPort
~cpp GetQueuedCompletionStatus
~cpp PostQueuedCompletionStatus
~cpp CloseHandle


fnwinter
내가 해석했지만 번역이 엿같다.fnwinter

IOCP 아직도 이해 못했다. 소스가 좀 헷갈리는거도 있지만.. 아무튼 익히고 나면 서버 프로그래밍할때 괘안을듯.. - 임인택

IOCP는 Select처럼 Socket을 관리하는 목적으로 쓰이는 데 윈도우즈에서 직접 껄떡거려서 Socket으로만 짜는 것
보다 훨 빠르다고 하네.. 책에 표로 대충 얼마나 좋은지 나오지. 버퍼도 한번 덜 쓰고 여러 소켓을 다 건들고..

흐.. 나도 IOCP 좀 봤는데.. cpu 가 dual 이상이 아니면.. 그냥 짜는게 나은거 같다.. -_-;; os 가 지멋대로 해주니.. ㅋㅋㅋ - 영현

IOCP...개념 이해하기가 난해하네요..ㅠ_ㅠ - icarus

서버는 대부분 듀얼이니 거의 IOCP로 짜야겠지. 그리고 OS가 지맘대로 해주긴 하지만 지맘대로 잘해주기 때문에 더 IOCP로 짜야겠지. 하지만!
요즘 컴퓨터 파워가 너무 좋아서! 힘들게 파워풀한 서버를 만드는 것도 좋지만! 그냥 컴퓨터 한대 더 사서 붙이는 것이.. 편하다는 생각..--fnwinter

최근에는 유사 기술로 epoll, kqueue 같은 것이 있다고는 하지만 실제 온라인 게임 회사의 게임서버는 거의 대부분 iocp를 이용해 구현한다고 함. WoW, Lineage etc... 이미 쌓여진 기술력이 iocp이니 ㅡ.ㅡ;; 타 기술에 비해 인력 수급이 그나마 쉽다고 함. 타 서버분야에 비해서 유난히 게임분야 서버에 NT가 선호되는 이유라고 함. - eternalbleu

kqueue 가 최근 유사기술이라고 하기에는.. FreeBSD 4.1 때부터 kqueue 가 나왔고 그때가 대략 2000년도. --1002
Retrieved from http://wiki.zeropage.org/wiki.php/IOCP
last modified 2021-02-07 05:23:26