본문 바로가기

카테고리 없음

OVERRAPED IO의 주의사항

https://learn.microsoft.com/en-us/windows/win32/sync/synchronization-and-overlapped-input-and-output

 

Synchronization and Overlapped Input and Output - Win32 apps

You can perform either synchronous or asynchronous (also called overlapped) I/O operations on files, named pipes, and serial communications devices.

learn.microsoft.com

When a function is called to perform an overlapped operation, the operation might be completed before the function returns. When this happens, the results are handled as if the operation had been performed synchronously. If the operation was not completed, however, the function's return value is FALSE, and the GetLastError function returns ERROR_IO_PENDING.

 

- overlapped io 를 수행할때 

1. 함수가 반환하기 전에 IO가 끝나는 경우는 result가 synchronous처럼 처리됨

2. IO가 끝나기전에 반환하는경우 return value는 FALSE이고 GetLastError는 ERROR_IO_PENDING을 반환

 

When performing multiple simultaneous overlapped operations on a single thread, the calling thread must specify an OVERLAPPED structure for each operation. Each OVERLAPPED structure must specify a handle to a different manual-reset event object.

단일 스레드에서 동시에 여러개의 overlapped 연산을 수행할때 각각의 연산에 대해서 overlapped 구조체를 지정해야함.

각각의 overlapped 구조체는 반드시 서로 다른 수동 리셋 event 객체에 대한 핸들을 지정해야함

 

 When a thread calls a function (such as the ReadFile function) to perform an overlapped operation, the calling thread must specify a pointer to an OVERLAPPED structure. (If this pointer is NULL, the function return value may incorrectly indicate that the operation completed.) All of the members of the OVERLAPPED structure must be initialized to zero unless an event will be used to signal completion of an I/O operation.

스레드가 overraped 연산을 위해 함수를 호출할때 overrlaped 구조체에 대한 포인터를 반드시 지정해야함.

만약 해당 pointer가 NULL이면 함수의 return value가 연산이 완료되었다는 (TRUE를 반환) 정확하지 않은 결과를 나타낼수있음

모든 overlapped구조체의 멤버는 사용되지 0으로 초기화해야함(event객체가 사용되는 경우는 해당 멤버는 예외) 

 

It is safer to use a separate event object for each overlapped operation, rather than specify no event object or reuse the same event object for multiple operations. If no event object is specified in the OVERLAPPED structure, the system signals the state of the file, named pipe, or communications device when the overlapped operation has been completed. Thus, you can specify these handles as synchronization objects in a wait function, though their use for this purpose can be difficult to manage because, when performing simultaneous overlapped operations on the same file, named pipe, or communications device, there is no way to know which operation caused the object's state to be signaled.

overlapped

구조체에 event 객체가 지정되지 않은 경우 시스템은 파일, 명명된 파이프, 커뮤니케이션 장치의 state를 signaled 로 바꿈. 따라서 장치의 커널오브젝트의 핸들을 wait function을 통해  동기화 객체로 사용 가능하지만

이러한 방법은 같은 장치에 대해서 동시에 여러가지의 IO연산이 발생하는 경우 어떤 IO연산으로 인해서 장치의 state가 signaled로 바뀌엇는지 알 수 없다는 단점이 존재함.

=> 따라서 각각의 연산에 해당하는 overlapped 구조체에 이벤트 핸들을 각각 등록하는게 안전함

 

A thread should not reuse an event with the assumption that the event will be signaled only by that thread's overlapped operation. An event is signaled on the same thread as the overlapped operation that is completing. Using the same event on multiple threads can lead to a race condition in which the event is signaled correctly for the thread whose operation completes first and prematurely for other threads using that event. Then, when the next overlapped operation completes, the event is signaled again for all threads using that event, and so on until all overlapped operations are complete.

멀티 스레드 환경에서 여러 스레드가 하나의 event 객체를 overrlaped IO의 완료 통지를 위해서 사용하는것은 race condition을 야기함

 

요약

1. return value

●  IO 완료 시점이  함수 반환시점보다 빠르면 synchronous 처럼 처리됨(nonzero)

●  IO  완료 시점이 함수 반환시점보다 느리면 0을 반환하고 GetLastError가 ERROR_IO_PENDING 설정됨

 

2. 하나의 스레드에서 벌어지는 모든 OVERLLAPED 연산에 대해서 별도의 OVERLLAPED구조체를 지정해야함

 

3. OVERRLAPED 연산을 위해 호출하는 함수에 LPOVERLLAPED 매개변수가 있으면 NULL로 설정하면 안됨.

 

4.  OVERLLAPED 구조체의 모든 멤버는 EVENT객체가 사용되는 경우 해당 멤버를 제외하고 모두 0으로 만들어야함

 

5. 하나의 장치에 대해 2개 이상의 OVERRAPED IO가 발생하는 경우 EVENT 객체를 사용하는게 바람직함

 

6. 여러 스레드가 하나의 EVENT 객체를 OVERLLAPED IO의 동기화 객체로 사용하는것은 race condition을 야기함