如何解决使用 fork() 和 wait() 进行并行处理以完成进程
我正在尝试创建某种“迷你外壳”。但特殊的因素是用户可以选择他的命令是否应该在后台处理。用户可以通过命令行末尾的字符 &
确定是否应在后台处理。
示例:
/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;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。