2014-03-24 3 views
1

SetFileCompletionNotificationModes() API를 사용하여 I/O 완료 포트 루프를 최적화했지만 제대로 작동하지 않는 것 같습니다. 내가 소켓과 핸들의 I에 대한 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS을 설정 하더라도 ReadFile()WriteFile()WSARecv()WSASend()synchronosly를 반환 할 경우/O 포트의 완료 콜백은 여전히라고도한다.SetFileCompletionNotificationModes가 제대로 작동하지 않는 것 같습니다.

MSDN에서 말하는 조건은 true 여야합니다 (완료 포트가 파일 핸들과 연결되어 있고 파일이 비동기 I/O 용으로 열렸으며 요청이 ERROR_PENDING을 반환하지 않고 즉시 성공을 반환 함). , 그리고 모두 사실이므로 I/O 완료 호출을받는 이유는 무엇입니까?

내가 SetFileCompletionNotificationModes() 전화는 성공, 그래서 아무 오류를 반환 또는 무엇이든지, 시스템이 I 명확하게 할 수있는, 윈도우 7 나는 내 소켓/핸들에 SetFileCompletionNotificationModes()을 활성화 한 후 시나리오를 복제 할 수있는 방법

경우 I/O 완료 콜백이 호출되지 않는지 확인하십시오.

나는 소켓의 버퍼가 꽤 크기 때문에 소켓에 ​​몇 바이트를 쓸 때가되었다고 추측했다. 완전히 채워지지 않았으므로 또 다른 몇 바이트의 다른 쓰기가 차단되어서는 안된다. 버퍼에 많은 공간이 있으므로 즉시 반환해야하지만 ERROR_IO_PENDING을 사용하지 않는 경우 동기식으로 처리 할 수 ​​있습니다. (어느 정도 유닉스와 유사한 방식으로 EWOULDBLOCK/EAGAIN : 몇 바이트 동안 write()을 호출하면 즉시 반환되고, 쓰기 버퍼에 여전히 공간이 있기 때문에 EAGAIN을 리턴하지 않는다.

글쎄 그건 그렇지 않습니다. 소켓에 몇 바이트를 여러 번 쓰는 경우에도 I/O 완료 콜백을 호출하여 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 설정의 이점을 누릴 수 있습니다.

중요한 것이 누락 되었습니까? 그것에 관한 어떤 단서?

참고 : 소켓이 IFS (Installable File Systems) 핸들을 반환하는 계층 적 서비스 공급자 (LSP)에서만 호환되는 경우 작동하지 않는다는 것을 알고 있습니다.하지만 그건 그렇지 않습니다. Btw 나는 파이프와 파일로 이것을 시도하고있다.

그들은 단지 유닉스 read()처럼, 차단 결코 로컬 파일에 write() 통화가 너무 즉시 반환해야합니다 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS과 핸들 세트 ReadFile()WriteFile() EWOULDBLOCK/EAGAIN 반환하지 않기 때문에 I/O 완료 콜백을 파일을 호출하지 안 ?

+0

코드보기 완료 포트를 연결하고 SetFileCompletionNotificationModes()를 호출합니다. 코드에 버그가있을 것으로 예상됩니다 ... –

+0

글쎄, 버그가 아닌지 확인하기 위해 코드를 다시 확인해보고 더 많은 테스트를 해보겠습니다. 이제 명명 된 파이프에서는 제대로 작동하지만 tcp/udp 소켓에서는 작동하지 않습니다. –

답변

2

네트워크 쓰기 완료 만 생성되지 않습니다. 이 일이 언제 생길지에 대해 추론하기는 다소 어렵습니다. 또한 다소 관련이없고 걱정할 것이 없습니다. FILE_SKIP_COMPLETION_PORT_ON_SUCCESS으로 겹쳐진 쓰기를 발행하면 쓰기 작업은 완료가 동 기적으로 발생한 경우에만 0을 반환합니다. 이 케이스를 올바르게 처리 할 코드를 작성하십시오 (recv에 필요한 코드와 동일합니다). 그리고 잊어 버리십시오. 가능한 경우 성능 및 컨텍스트 전환 이점을, 그렇지 않은 경우 코드가 올바르게 작동하도록합니다.

파일 시스템 액세스는 파일 시스템 드라이버 및 실제 하드웨어에 따라 다릅니다. 일부 하드웨어에서 비동기 파일 쓰기를 수행하는 것이 얼마나 어려운지에 대한 정보는 here을 참조하십시오. 그런 다음 내가 '일반'SATA 디스크가있는 워크 스테이션에서 하드웨어 RAID가있는 서버에 이르기까지 모든 테스트가 서로 다르고 모든 쓰기가 항상 완전히 비동기였던 점에 유의하십시오.

1

당신이 documentation에 언급 된 4 상태를 확인해야합니다 : 파일 핸들 매개 변수가 소켓이

,이 모드는 설치 가능 파일 시스템을 반환 계층화 된 서비스 공급자 (LSP) 만 호환됩니다 (IFS) 핸들. 비 IFS LSP가 설치되어 있는지 여부를 확인하려면 WSAEnumProtocols 함수를 사용하고 반환 된 각 WSAPROTOCOL_INFO 구조체의 dwServiceFlag1 멤버를 검사하십시오. XP1_IFS_HANDLES (0x20000) 비트가 지워지면 지정된 LSP가 IFS LSP가 아닙니다. 비 IFS LSP가있는 공급 업체는 Windows 필터링 플랫폼 (WFP)으로 마이그레이션하는 것이 좋습니다.

또한이 MSDN 지원 티켓을 읽어 귀하가 제공 한 데이터 버퍼가 더 이상 네트워크 스택에 의해 필요한 경우

SetFileCompletionNotificationModes API causes an I/O completion port not to work correctly if a non-IFS LSP is installed

+0

이전에 게시 한 것처럼 소켓에는 IFS LSP가 있으며 AFD 드라이버 (예 : WSAPROTOCOL_INFOW.ProtocolChain.ChainLen)에 직접 연결됩니다. 1)이므로 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS가 소켓에서 작동하지 않아야합니다. 이상한 것은 파이프 나 파일로도 시도하고 있는데 거기에서도 작동하지 않는 것 같습니다 ... –

관련 문제