gpt4 book ai didi

c++进程在两个子进程之间进行管道连接时挂起

转载 作者:行者123 更新时间:2023-11-30 05:03:53 26 4
gpt4 key购买 nike

我正在尝试将数据从一个子进程传输到另一个子进程。当我运行它时,它挂起。如果我不让它等待第一个子进程,它会回到循环顶部提示命令而不给出预期的输出,当我提示它退出时,它会转储我期望的所有输出。我让它只与一个子进程一起工作,但随后第二个 execvp 杀死了父进程,我没有回到循环的顶部提示更多命令。

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>

using namespace std;

int main(int argc, const char * argv[]) {

bool quit=0;
char quitArray[] = "quit";
int pipeReturnValue, fork1ReturnValue, fork2ReturnValue, pipefd[2], checkForQuit;

//Enter a loop where each iteration prompts for two single-line inputs
while (!quit) {

//Get command 1
char command1[128];
printf("Enter command 1: ");
fgets(command1,128,stdin);
command1[strlen(command1) -1] = 0;

//Exit if user enters quit
checkForQuit = strncmp(command1, quitArray, 4);
if (checkForQuit == 0) {
exit(0);
}

//Get command 2
char command2[128];
printf("Enter command 2: ");
fgets(command2,128,stdin);
command2[strlen(command2) -1] = 0;

//Exit if user enters quit
checkForQuit = strncmp(command2, quitArray, 4);
if (checkForQuit == 0) {
exit(0);
}

//Open pipe
pipeReturnValue = pipe(pipefd);
if (pipeReturnValue < 0) {
perror("Pipe failed");
exit(1);
}

//Fork 1
fork1ReturnValue = fork();
if(fork1ReturnValue < 0) {
perror("Fork failed");
exit(1);
}

else if (fork1ReturnValue == 0) {

//Fork 2
fork2ReturnValue = fork();
if (fork2ReturnValue < 0) {
perror("Fork 2 failed");
}
else if (fork2ReturnValue == 0) {
//close read end of pipe
close(pipefd[0]);
//parse command 1 arguments
//store tokens in array
char *arguments[6] = {};
arguments[0] = strtok(command1, " ");
int tokenCounter = 0;
while (arguments[tokenCounter] != NULL) {
tokenCounter++;
arguments[tokenCounter] = strtok(NULL, " ");
}
//dup stdo to pipe
dup2(pipefd[1], 1);
//execute arguments
execvp(arguments[0], arguments);
}
else {
wait(&fork2ReturnValue);
//close write end of pipe
close(pipefd[1]);
//parse command 2 arguments
//store tokens in array
char *arguments[6] = {};
arguments[0] = strtok(command2, " ");
int tokenCounter = 0;
while (arguments[tokenCounter] != NULL) {
tokenCounter++;
arguments[tokenCounter] = strtok(NULL, " ");
}
//dup stdin to pipe
dup2(pipefd[0], 0);
//exec
execvp(arguments[0], arguments);
}
}
else {
wait(&fork1ReturnValue);
}
}
return 0;

最佳答案

我终于明白了。我需要在第一次 fork 之后而不是之前打开管道。

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>

using namespace std;

int main(int argc, const char * argv[]) {

bool quit=0;
char command1[128],
command2[128],
quitArray[] = "quit";
int pipeReturnValue,
fork1ReturnValue,
fork2ReturnValue,
checkForQuit,
pipefd[2];

//Loop where each iteration prompts for two single-line inputs
while (!quit) {

//Get command 1
printf("Enter command 1: ");
fgets(command1,128,stdin);
command1[strlen(command1) -1] = 0;

//Exit if user enters quit
checkForQuit = strncmp(command1, quitArray, 4);
if (checkForQuit == 0) {
quit = 1;
exit(0);
}

//Get command 2 and trim trailing new line character
printf("Enter command 2: ");
fgets(command2,128,stdin);
command2[strlen(command2) -1] = 0;

//Exit if user enters quit
checkForQuit = strncmp(command2, quitArray, 4);
if (checkForQuit == 0) {
quit = 1;
exit(0);
}

//Fork to create 1st child process, return error if fork fails
fork1ReturnValue = fork();
if(fork1ReturnValue < 0) {
perror("Fork 1 failed");
exit(1);
}

//Open pipe, return error if fork fails
pipeReturnValue = pipe(pipefd);
if (pipeReturnValue < 0) {
perror("Pipe failed");
exit(1);
}

//First child process
else if (fork1ReturnValue == 0) {

//Fork to create 2nd child process, return error if fork fails
fork2ReturnValue = fork();
if (fork2ReturnValue < 0) {
perror("Fork 2 failed");
}

//Second child process
else if (fork2ReturnValue == 0) {

//close read end of pipe
close(pipefd[0]);

//Parse command 1 arguments, store tokens in an array
char *arguments[6] = {};
arguments[0] = strtok(command1, " ");
int tokenCounter = 0;
while (arguments[tokenCounter] != NULL) {
tokenCounter++;
arguments[tokenCounter] = strtok(NULL, " ");
}

//Dup standard output to write side of pipe
dup2(pipefd[1], 1);

//Execute arguments from command 1
execvp(arguments[0], arguments);
}

//First child code continued
else {

//Wait for child 2 to to terminate
wait(&fork2ReturnValue);

//Close write end of pipe
close(pipefd[1]);

//Parse command 2 arguments, store tokens in array
char *arguments[6] = {};
arguments[0] = strtok(command2, " ");
int tokenCounter = 0;
while (arguments[tokenCounter] != NULL) {
tokenCounter++;
arguments[tokenCounter] = strtok(NULL, " ");
}

//dup standard input to read side of pipe
dup2(pipefd[0], 0);

//Execute arguments from command 2
execvp(arguments[0], arguments);
}
}

//Parent process continued
else {

//Wait for child 1 to terminate
wait(&fork1ReturnValue);
}

//return to top of loop
}
return 0;
}

关于c++进程在两个子进程之间进行管道连接时挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49204730/

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