gpt4 book ai didi

c++ - 使用 ReadFile 和 WriteFile 时出现死锁

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:39:42 25 4
gpt4 key购买 nike

我正在做一个学校项目,我试图在子进程的 StdOut 中显示在父进程的 StdIn 中写入的内容;反之亦然,即在父 StdOut 上显示在子进程 StdIn 上写入的内容,但我遇到了 ReadFile 和 WriteFile 操作的死锁。

根据我在研究该主题期间收集到的信息,这是使用同步管道时的常见问题。

是否应该通过事件来同步管道上的读写操作?你建议其他方法吗?任何建议将不胜感激,提前致谢。

Parent.cpp

#include <windows.h>
#include <iostream>
#include <stdio.h>

//read handle pipe1
HANDLE r1 = NULL;

//write handle pip1
HANDLE w1 = NULL;

//read handle pipe2
HANDLE r2 = NULL;

//write handle for pipe2
HANDLE w2 = NULL;

#define BUFSIZE 4096

void CreateChildProcess() {
TCHAR applicationName[] = TEXT("Child");
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL success = FALSE;

ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));

si.cb = sizeof(STARTUPINFO);
si.hStdError = w1;
si.hStdOutput = w1;
si.hStdInput = r2;
si.dwFlags |= STARTF_USESTDHANDLES;


success = CreateProcess(NULL, applicationName, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);

if (!success) {
printf("Error creating child process \n");
}
else {

printf("Child process successfuly created \n");
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
void WriteToPipe() {
DWORD read, written;
CHAR chBuf[BUFSIZE];
BOOL success = FALSE;

HANDLE pStdIn = GetStdHandle(STD_INPUT_HANDLE);

for (;;)
{
success = ReadFile(pStdIn, chBuf, BUFSIZE, &read, NULL);
if (!success || read == 0) break;

success = WriteFile(w2, chBuf, read, &written, NULL);
if (!success) break;
}
}

void ReadFromPipe() {
DWORD read, written;
CHAR chBuf[BUFSIZE];
BOOL success = FALSE;

HANDLE pStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

for (;;)
{
success = ReadFile(r1, chBuf, BUFSIZE, &read, NULL);
if (!success || read == 0) break;

success = WriteFile(pStdOut, chBuf, read, &written, NULL);
if (!success) break;
}
}

int main()
{

DWORD dRead, dWritten;
CHAR chBuf[BUFSIZE];
BOOL bSuccess = FALSE;

SECURITY_ATTRIBUTES secAttr;
secAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
secAttr.bInheritHandle = TRUE;
secAttr.lpSecurityDescriptor = NULL;

printf("Creating first pipe\n");
if (!CreatePipe(&r1, &w1, &secAttr, 0)) {
printf("\nError creating first pipe\n");
}
printf("Creating second pipe\n");
if (!CreatePipe(&r2, &w2, &secAttr, 0)) {
printf("Error creating second pipe \n");
}


if (!SetHandleInformation(r1, HANDLE_FLAG_INHERIT, 0)) {
printf("r1 SetHandleInformation \n");
}
if (!SetHandleInformation(w2, HANDLE_FLAG_INHERIT, 0)) {
printf("w2 SetHandleInformation \n");
}


printf("\nCreating child process..... \n");
CreateChildProcess();

WriteToPipe();
ReadFromPipe();

return 0;
}

Child.cpp

#include <windows.h>
#include <stdio.h>
#include "pch.h"

#define BUFSIZE 4096

int main()
{
DWORD dRead, dWritten;
CHAR chBuf[BUFSIZE];
BOOL success = FALSE;
HANDLE stdIn = GetStdHandle(STD_INPUT_HANDLE);
HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);


if (stdIn == INVALID_HANDLE_VALUE || stdOut == INVALID_HANDLE_VALUE) {
ExitProcess(1);
}

for (;;) {
success = ReadFile(stdIn, chBuf, BUFSIZE, &dRead, NULL);
if (!success || dRead == 0) break;
success = WriteFile(stdOut, chBuf, dRead, &dWritten, NULL);
if (!success) break;
}

return 0;
}

最佳答案

您将无法在父 StdOut 上显示在子进程 StdIn 上写入的内容,因为子进程的 stdIn 句柄已设置为“r2”。这样您就无法手动在子进程中插入任何内容。我建议使用 namepipe ,这样 child 的 std 句柄就不会与其他管道句柄混合。

for(;;)等于while(1),ReadFile()直到接收到数据才会返回,所以如果没有异常(排除没有数据传入),循环永远不会中断,并且代码不会继续到 ReadFromPipe();

使用 namepipe 的 Overlap 模式或者尝试创建 2 个线程和 2 个 namepipes,一个从 namepipe 读取然后打印出来,另一个从 stdin 读取然后写入 namepipe(在两个进程中)。

关于c++ - 使用 ReadFile 和 WriteFile 时出现死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53695551/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com