C++ 如何使子进程在完成后立即返回以运行父进程(当我们执行fork时)?
我编写了一个模拟cp函数(在bash中复制)的函数,基本上该函数将一个文件作为输入,并将其复制到dest文件:C++ 如何使子进程在完成后立即返回以运行父进程(当我们执行fork时)?,c++,fork,C++,Fork,我编写了一个模拟cp函数(在bash中复制)的函数,基本上该函数将一个文件作为输入,并将其复制到dest文件: cp sourceFile destFile . 如果行尾有一个“&”,cp函数可以在前端或后端运行(cp sourceFile destFile&) 为了支持这一点,我使用了fork,儿子基本上复制了文件,他父亲如果命令是fore ground,他会等待孩子,否则如果命令是back ground,我们就不会等待(我们将它添加到特定列表中) 我的问题是,在son完成代码退出后,如果命
cp sourceFile destFile .
如果行尾有一个“&”,cp函数可以在前端或后端运行(cp sourceFile destFile&
)
为了支持这一点,我使用了fork,儿子基本上复制了文件,他父亲如果命令是fore ground,他会等待孩子,否则如果命令是back ground,我们就不会等待(我们将它添加到特定列表中)
我的问题是,在son完成代码退出后,如果命令在前台运行,cp函数将返回,但当它退出cp函数时,它会打印一些内容,我不希望发生这种情况:(
(最后举例)
我的职能:
void CopyCommand::execute() {
char *buff = new char[1024]();
int fdRead = open(args[1], O_RDONLY);
if (fdRead == -1) {
perror("smash error: open failed");
return;
}
int fdWrite = open(args[2], O_WRONLY | O_TRUNC);
if (fdWrite ==-1) {
fdWrite = open(args[2], O_WRONLY | O_CREAT, 0666);
if (fdWrite == -1) {
perror("smash error: open failed");
return;
}
}
PID = fork();
if (PID == 0) {
setpgrp();
int count = read(fdRead, buff, 1); /// read from the file fd1 into fd2
while (count != -1) {
if (!count) {
break;
}
if (write(fdWrite, buff, 1) == -1) {
perror("smash error: write failed");
return; // not sure if we should return
}
count = read(fdRead, buff, 1);
if (count == -1) {
perror("smash error: read failed");
return;
}
}
return ;
} if (PID > 0) { // if i am the father then i will :
if (isBackground) {
// if cp command is running in the background then add it to the jobs list
SmallShell::getInstance().SmallShellGetJobs()->removeFinishedJobs();
SmallShell::getInstance().Jobs_List.addJob(SmallShell::getInstance().currentCommand, false);
cout << "smash: " << args[1] << " was copied to " << args[2] << endl;
return;
} else {
int status;
waitpid(PID, &status, WUNTRACED);
cout << "smash: " << args[1] << " was copied to " << args[2] << endl;
return;
}
} else {
perror("smash error: fork failed");
}
}
产出将是:
outside of cp function :(
smash: test_src_1.txt was copied to test_newdest_1.txt
fork
的工作方式与您想象的不同。子进程在终止之前一直存在,并继承父进程的调用堆栈等内容;当您在子进程中return
时,您只需转到调用函数
您需要使用exit
或同一系列中的某些功能。例如:
if (PID == 0) {
setpgrp();
int count = read(fdRead, buff, 1); /// read from the file fd1 into fd2
while (count != -1) {
if (!count) {
break;
}
if (write(fdWrite, buff, 1) == -1) {
perror("smash error: write failed");
exit(0); // not sure if we should return
}
count = read(fdRead, buff, 1);
if (count == -1) {
perror("smash error: read failed");
exit(1);
}
}
exit(1) ;
}
请注意,这是在bash中添加
&
时的行为(只需尝试回显测试&
)。显示的代码存在可怕的内存泄漏。您能否解释一下,您希望通过手动new
ing一个缓冲区而不是使用std::vector
为您管理此分配来完成什么,对吗?现在您必须记住始终删除它。似乎您从未在任何地方执行过。您为什么决定新的
缓冲区,迫使你自己去处理额外的开销,无论你从这个函数返回到哪里,你都要记住它来删除它,而你从来没有这样做过。使用std::vector
并让它去做这些事情,这对你来说不是更有意义吗?但是我没有把&放在最前面我要测试的行结束测试确定我要将其更改为vector,但这不是我现在的主要问题!我的问题是为什么在子复制完文件后,它会从函数中返回并打印一些内容,然后返回以运行父进程??“父/子”,而不是“父/子”退出基本上结束了子进程?返回到父进程?它实际上起了作用我很高兴!!!谢谢exit
终止当前进程。没有任何“返回到父进程”,因为父进程仍然独立运行(尽管您使用waitpid
)进行阻止。这确实很有帮助!谢谢:)
if (PID == 0) {
setpgrp();
int count = read(fdRead, buff, 1); /// read from the file fd1 into fd2
while (count != -1) {
if (!count) {
break;
}
if (write(fdWrite, buff, 1) == -1) {
perror("smash error: write failed");
exit(0); // not sure if we should return
}
count = read(fdRead, buff, 1);
if (count == -1) {
perror("smash error: read failed");
exit(1);
}
}
exit(1) ;
}