c++ - 使用 fork() 和 wait() 进行并行处理以完成进程
问题描述
我正在尝试创建某种“minishell”。但特殊因素是用户可以选择他的命令是否应该在后台处理。用户可以使用&
命令行末尾的字符来确定是否应该在后台处理。
例子:
/tmp > date
Tue Apr 27 09:53:32 CEST 2021
/tmp > sleep 10 // have to wait to be able to create a command again
/tmp > date
Tue Apr 27 09:56:33 CEST 2021
/tmp > sleep 10 & // sleep is processing in the background (don't have to wait)
[28727] // printing PID
/tmp > ps
PID TT STAT TIME COMMAND
96440 s000 S 0:00.04 -bash
97144 s000 S+ 0:00.00 minishell.exe
28727 s000 S+ 0:00.00 sleep 10
/tmp > date
Process 28727 done (sleep 20) // notify the user that the process is done
Tue Apr 27 10:12:38 CEST 2021
一切都运行良好,直到后台进程完成。命令行/shell 布局无法按预期工作。我没有为要输入的下一个命令打印我的计算机名称和文件路径:
computername@miniShell:/mnt/c/Users/name/desktop/minishell$ sleep 10 &
[28727]
//...
// after 10 sec
computername@miniShell:/mnt/c/Users/name/desktop/minishell$ ps
computername@miniShell:/mnt/c/Users/name/desktop/minishell$ PID TTY TIME CMD
28648 pts/1 00:00:00 bash
28722 pts/1 00:00:00 minishell.exe
28730 pts/1 00:00:00 ps
date // not getting computer name and path printed
computername@miniShell:/mnt/c/Users/name/desktop/minishell$ Mon Apr 26 17:44:36 CEST 2021
date // next command-line without computer-name and path...
//...
我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <pwd.h>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
bool isBackground(char* string){
char* c;
int index;
if(c = strchr(string, '\0'))
index = (int)(c - string);
for(int i = (index-1); i>=0; i--){
if((string[i] == '&') && (string[i-1] == ' '))
return true;
if((string[i] != ' '))
return false;
}
return false;
}
int main(int argc, char * argv[]){
int childPid;
int tempPid;
int status;
char cwd[256];
char input[256];
char inputCopy[256];
char *command;
char *parameters[60];
bool background = false;
bool normalState = true;
while(1) {
//return user-info and current working directory if not background
getcwd(cwd, sizeof(cwd));
printf("%s@miniShell:%s$ ", getpwuid(getuid())->pw_name, cwd);
//read command and parameters
fgets(input, 256, stdin);
command = strchr(input, '\n');
//replace/delete /n-char if found
if(command){
*command = '\0';
}
//exit exception
if(strncmp(input, "exit",4)==0){
exit(0);
}
// determine if background processing is requested
// delete trailing &
if(background = isBackground(input)){
command = strchr(input, '&');
*command = '\0';
strncpy(inputCopy, input, 256);
}
// cd exception
if(strncmp(input, "cd ",3)==0){
strtok(input, " ");
command = strtok(NULL, "\0");
if(chdir(command) != 0){
perror("Error while changing directory. Please try again!");
}
continue;
}
if ((childPid = fork()) == -1) {
fprintf(stderr,"can't fork\n");
exit(0);
}else if (childPid == 0) { /* child process*/
command = strtok(input, " ");
parameters[0] = command;
int i = 1;
while((parameters[i] = strtok(NULL, " ")) != NULL){
i++;
}
if(execvp(command, parameters) < 0){
cout << command << ": command not found!" << endl;
}
exit(0);
} else { /* parent process */
if(background){
tempPid = childPid;
cout << "[" << childPid << "]" << endl;
continue;
}
//wait(&status);
int waited;
if((waited = wait(&status)) == tempPid){
cout << "Process " << waited << " done (" << inputCopy << ")" << endl;
normalState = false;
}
} /* endif parent */
} /* end while forever */
return 0;
}
解决方案
推荐阅读
- javascript - jQuery修剪功能没有在最后删除空间
- c++ - 为什么 QList 不能作为 QML GridView 的模型?
- reactjs - “gatsby-plugin-purgecss”将每个页面的所有使用的CSS添加到所有页面,有没有办法防止这种情况?
- javascript - JS:扁平化未知数量的嵌套数组的最有效方法是什么?
- wordpress - 将 .com 域从 wordpress.com 转移到自托管网站
- asp.net-core - 如何使用编辑器模板渲染带有 Razor 的菜单?
- python - DataFlow 部署失败并出现“对象没有属性 watermark_estimator_provider”错误
- vba - 强制注销脚本
- javascript - JS - 自动更改继承类
- nnet - 我如何在 mlr3 中包含学习者