WaitNamedPipe
기능을 사용하면 파이프 클라이언트 응용 프로그램이 명명 된 파이프 서버에서 사용 가능한 연결을 동 기적으로 대기 할 수 있습니다. 그런 다음 CreateFile
을 호출하여 파이프를 클라이언트로 엽니 다. 의사 코드 :WaitNamedPipe 대신 겹쳐진 I/O 란 무엇입니까?
// loop works around race condition with WaitNamedPipe and CreateFile
HANDLE hPipe;
while (true) {
if (WaitNamedPipe says connection is ready) {
hPipe = CreateFile(...);
if (hPipe ok or last error is NOT pipe busy) {
break; // hPipe is valid or last error is set
}
} else {
break; // WaitNamedPipe failed
}
}
문제는 모두 동기식 호출을 차단하는 것입니다. 이것을 비동기 적으로 수행하는 좋은 방법은 무엇입니까? 예를 들어, 중복 된 I/O를 사용하는 API를 찾을 수없는 것 같습니다. 예를 들어, 파이프 서버ConnectNamedPipe
함수 비동기 클라이언트 기다려야하는 서버 lpOverlapped
허용하는 매개 변수를 제공한다. 그런 다음 파이프 서버는 WaitForMultipleObjects을 호출하여 I/O 작업이 완료되거나 다른 이벤트가 신호 될 때까지 기다릴 수 있습니다 (예 : 스레드가 보류중인 I/O를 취소하고 종료하도록 알리는 이벤트).
내가 생각할 수있는 유일한 방법은 WaitNamedPipe
을 짧은 시간 제한의 루프에서 호출하고 시간이 초과되면 다른 신호를 확인하는 것입니다. 또는 루프 호출 CreateFile
에서 다른 신호를 확인한 다음 짧은 지연 (또는 WaitNamedPipe
)으로 Sleep
으로 전화하십시오. 예를 들면 다음과 같습니다.
HANDLE hPipe;
while (true) {
hPipe = CreateFile(...);
if (hPipe not valid and pipe is busy) {
// sleep 100 milliseconds; alternatively, call WaitNamedPipe with timeout
Sleep(100);
// TODO: check other signals here to see if we should abort I/O
} else
break;
}
그러나이 방법은 내 생각에 높은 천국으로 악취를냅니다. 파이프를 잠시 사용할 수 없다면 스레드는 계속 실행됩니다. CPU 사용, 전원 사용, 메모리 페이지가 RAM에 남아 있어야합니다. 내 생각에 Sleep
또는 짧은 시간 제한에 의존하는 스레드는 제대로 수행되지 않습니다. 엉성한 멀티 스레드 프로그래밍의 징조이다.
하지만이 경우 대체 방법은 무엇입니까?
하나의 분명한 해결책은 별도의 스레드에서 WaitNamedPipe를 호출하는 것입니다. IIRC에서 몇몇 비동기 IO 함수는 실제적으로 스레딩을 사용하기 때문에 비효율적이지 않습니다. –
이 코드로 해결되는 경쟁 조건에 대해 더 자세히 알려주십시오. MS 설명서 샘플 클라이언트 코드는 CreateFile을 먼저 호출하고 Create가 파이프 바쁨으로 실패하면 WaitNamedPipe 만 호출합니다. 루프에서 적절한 대기 시간 초과와 함께 수행하십시오. 그것은 항상 내 경험에서 일했습니다. 이 오류는 두 클라이언트가 하나의 파이프에 대해 수행 할 때만 발생하지만 경쟁이 아닙니다. 한 명의 고객이 연결되고 다른 고객이 잠을 잘 때까지 기다렸다가 다시 시도합니다. –
@ 마크 : 문서에 있습니다. WaitNamedPipe가 성공하면 다른 스레드가 처음으로 건너 뛰어서 CreateFile이 계속 실패 할 수 있습니다. 경쟁 조건입니다. 두 개 이상의 스레드가 파이프를 열기 위해 경쟁 중입니다. 경합 조건 주위에서 루프를 작동 시키므로 OP 코드의 주석이 사용됩니다. 그것은 그가 우리에게 풀어야 할 문제는 아닙니다. –