C++Builder 程序员博客
2 Jul
CreatePipe(&hStdOutRead, &hStdOutWrite, &sa, 0);
怎么读取(单线程)管道hStdOutRead里面的数据,并且不阻塞主线程?
管道自己摸索,实在搞不定,总是阻塞线程.
请问,哪有管道方面的资料或者书籍?
买了四本C++BUILDER书,提都没提管道,恨不得拿来当柴烧了算了.
还有C++BUILDER帮补文件,就是找不出一个关于管道的实例来,
管道是API里的东东,BCB的书当然不会讲啦。
你可以看看MSDN,这个东东最好是用多线程,楼主就别偷懒啦:-)
单线程不阻塞,想想就可以了。
如果用多线程,请问:
1.子线程读取管道数据,用RichEdit显示出来,怎么办?
2.RichEdit必须放在主线程?子线程操作主线程的RichEdit如要用到同步处理吗?
3.RichEdit可以放在子线程(假设是另外一个子线程,专用来显示管道数据)吗?如果可以,怎么实现?
多谢楼上。
才业余学C++builder不久,单线程都不会用,多线程更不敢用。
多线程会有诸多麻烦,最重要的是不能使用组件,或者使用组件有限制,而这种限制我是一点都不清楚。
所以要尽量避免用多线程。
CreatePipe(&hStdOutRead, &hStdOutWrite, &sa, 0);
如果用命名管道,怎么实现类似的功能?
你使用命名管道的目的是什么?
#include <windows.h> #include <stdio.h> #define BUFSIZE 4096 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr, hInputFile, hStdout; BOOL CreateChildProcess(VOID); VOID WriteToPipe(VOID); VOID ReadFromPipe(VOID); VOID ErrorExit(LPTSTR); VOID ErrMsg(LPTSTR, BOOL); int main(int argc, char *argv[]) { SECURITY_ATTRIBUTES saAttr; BOOL fSuccess; // Set the bInheritHandle flag so pipe handles are inherited. saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; // Get the handle to the current STDOUT. hStdout = GetStdHandle(STD_OUTPUT_HANDLE); // Create a pipe for the child process’s STDOUT. if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) ErrorExit("Stdout pipe creation failed\n"); // Ensure the read handle to the pipe for STDOUT is not inherited. SetHandleInformation( hChildStdoutRd, HANDLE_FLAG_INHERIT, 0); // Create a pipe for the child process’s STDIN. if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) ErrorExit("Stdin pipe creation failed\n"); // Ensure the write handle to the pipe for STDIN is not inherited. SetHandleInformation( hChildStdinWr, HANDLE_FLAG_INHERIT, 0); // Now create the child process. fSuccess = CreateChildProcess(); if (! fSuccess) ErrorExit("Create process failed with"); // Get a handle to the parent’s input file. if (argc == 1) ErrorExit("Please specify an input file"); printf( "Debug: argv[1] = %s\n", argv[1]); hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); if (hInputFile == INVALID_HANDLE_VALUE) ErrorExit("CreateFile failed"); // Write to pipe that is the standard input for a child process. WriteToPipe(); // Read from pipe that is the standard output for child process. ReadFromPipe(); return 0; } BOOL CreateChildProcess() { TCHAR szCmdline[]=TEXT("child"); PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; BOOL bFuncRetn = FALSE; // Set up members of the PROCESS_INFORMATION structure. ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); // Set up members of the STARTUPINFO structure. ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.hStdError = hChildStdoutWr; siStartInfo.hStdOutput = hChildStdoutWr; siStartInfo.hStdInput = hChildStdinRd; siStartInfo.dwFlags |= STARTF_USESTDHANDLES; // Create the child process. bFuncRetn = CreateProcess(NULL, szCmdline, // command line NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited 0, // creation flags NULL, // use parent’s environment NULL, // use parent’s current directory &siStartInfo, // STARTUPINFO pointer &piProcInfo); // receives PROCESS_INFORMATION if (bFuncRetn == 0) ErrorExit("CreateProcess failed\n"); else { CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); return bFuncRetn; } } VOID WriteToPipe(VOID) { DWORD dwRead, dwWritten; CHAR chBuf[BUFSIZE]; // Read from a file and write its contents to a pipe. for (;;) { if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) || dwRead == 0) break; if (! WriteFile(hChildStdinWr, chBuf, dwRead, &dwWritten, NULL)) break; } // Close the pipe handle so the child process stops reading. if (! CloseHandle(hChildStdinWr)) ErrorExit("Close pipe failed\n"); } VOID ReadFromPipe(VOID) { DWORD dwRead, dwWritten; CHAR chBuf[BUFSIZE]; // Close the write end of the pipe before reading from the // read end of the pipe. if (!CloseHandle(hChildStdoutWr)) ErrorExit("Closing handle failed"); // Read output from the child process, and write to parent’s STDOUT. for (;;) { if( !ReadFile( hChildStdoutRd, chBuf, BUFSIZE, &dwRead, NULL) || dwRead == 0) break; if (! WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL)) break; } } VOID ErrorExit (LPTSTR lpszMessage) { fprintf(stderr, "%s\n", lpszMessage); ExitProcess(0); }