자식 프로세스의 stderr
에서 읽으려고합니다. 데이터는 sprintf(stderr, "some debug info\n")
으로 작성된 텍스트 행입니다. 완료 루틴과 함께 ReadFileE
x를 사용하고 있습니다. 나는 얼마나 많은 문장의 줄이나 각 줄이 얼마나 길어야할지 모른다. 그래서 nNumberOfBytesToRead
매개 변수로 무엇을 넣을까요?ReadFileEx, 가변 길이 - 몇 가지 질문
내 생각 엔 4k를 만들 버퍼의 최대 크기를 넣었습니다. 그게 최적의 크기인지는 모르겠지만. stderr
에 쓰여진 줄이 4k보다 짧으면 완료 루틴이 실행되지 않는다고 추측합니다. 나는 4k에 도달했지만 더 많은 데이터가 남아있을 때 완료 루틴 내에서 다른 ReadFileEx
을 발사해야한다고 생각합니다. GetLastError
이 ERROR_MORE_DATA
을 반환 할 것이므로이 경우를 알 수 있습니다. 버퍼가 꽉 찼지 만 자식 프로세스가 종료되었을 때 전화를 받기를 바라고 있습니다. 자식 프로세스가 종료 될 때 완료 콜백을 얻었는지 확신 할 수 없습니다. 왜냐하면 자식을 만들 때 stderr
쓰기 핸들을 전달했기 때문입니다. 어쩌면 내가 내가 그 핸들을 닫을 때 콜백을 얻을 수 있습니다. 자녀가 을 내 독서 인 stderr
으로 닫을 때 경쟁 조건이 있습니까?
Attr.bInheritHandle = true
CreatePipe(&hr, &hw, &Attr, 0) and SetHandleInformation(hX, HANDLE_FLAG_INHERIT) on hX the child uses.
Si.hStdXXX = handles from CreatePipe that child uses
CreateProcess(inherit=true, &Si)
세부 사항 (전송 확장은 오류를 발생 래퍼) : : 여기
프로세스와 핸들이 만들어지는 방법의 사이비 코드CreatePipe
로 만든
HANDLE Create() {
STARTUPINFO SI, *pSI = NULL;
bool fInherit = m_fInherit;
if (m_fStdOut || m_fStdIn || m_fStdErr) {
fInherit = true;
SECURITY_ATTRIBUTES Attr;
Attr.nLength = sizeof(SECURITY_ATTRIBUTES);
Attr.bInheritHandle = TRUE;
Attr.lpSecurityDescriptor = NULL;
if (m_fStdOut) // Create a pipe for the child process's STDOUT. The child will use the write.
CHandle::CreatePipe(m_hStdOutR, m_hStdOutW, &Attr, CP_INHERIT_WRITE);
if (m_fStdErr) // Create a pipe for the child process's STDERR. The child will use the write.
CHandle::CreatePipe(m_hStdErrR, m_hStdErrW, &Attr, CP_INHERIT_WRITE);
if (m_fStdIn) // Create a pipe for the child process's STDIN. The child will use the read.
CHandle::CreatePipe(m_hStdInR, m_hStdInW, &Attr, CP_INHERIT_READ);
// Set up members of the STARTUPINFO structure.
// This structure specifies the STDIN and STDOUT handles for redirection.
ZeroStruct(SI);
SI.cb = sizeof(STARTUPINFO);
SI.hStdError = m_hStdErrW, SI.hStdOutput = m_hStdOutW, SI.hStdInput = m_hStdInR;
SI.dwFlags |= STARTF_USESTDHANDLES;
pSI = &SI;
}
// m_fCpu, m_fNuma are masks to set affinity to cpus or numas
CreateProcessTx(NULL, m_szCmdLine, fInherit, m_fFlags, pSI, &m_pi, m_fCpu, m_fNuma, 5);
m_hProc = m_pi.hProcess;
m_hThread = m_pi.hThread;
if (!m_fThread)
m_hThread.Close();
return m_hProc;
}
static void CreatePipe(CHandle &hRead, CHandle &hWrite, SECURITY_ATTRIBUTES* pAttr, BYTE fInheritMask) {
HANDLE hReadTmp = NULL, hWriteTmp = NULL;
CreatePipeTx(hReadTmp, hWriteTmp, pAttr);
SetHandleInformation(hReadTmp, HANDLE_FLAG_INHERIT, (fInheritMask&CP_INHERIT_READ) ? HANDLE_FLAG_INHERIT : 0);
SetHandleInformation(hWriteTmp, HANDLE_FLAG_INHERIT, (fInheritMask&CP_INHERIT_WRITE) ? HANDLE_FLAG_INHERIT : 0);
hRead = hReadTmp;
hWrite = hWriteTmp;
}
'CreatePipe'로 생성 된 핸들을 사용하고 있습니까? –
@RR 좋은 지적. 파이프와 프로세스를 만드는 코드 부분을 추가하기 위해이 게시물을 편집했습니다. – johnnycrash