C++ 理解C+中的fork、exec和wait+;(Linux)
我对在linux中使用这些不同类型的系统调用非常陌生,这让我感到非常困惑。有了这个,我只要求朝正确的方向推进/开始,而不是完成。 使用C++ 理解C+中的fork、exec和wait+;(Linux),c++,linux,fork,exec,wait,C++,Linux,Fork,Exec,Wait,我对在linux中使用这些不同类型的系统调用非常陌生,这让我感到非常困惑。有了这个,我只要求朝正确的方向推进/开始,而不是完成。 使用fork、exec和wait,我已经阅读了它们,但这对我的处境仍然没有真正的帮助。 我要做的是: 打印promt并等待用户输入最多包含四个参数或选项的命令。“退出”将停止程序 一些示例,mkdir blah,创建目录,然后提示输入新命令,touch blah/this blah/that blah/there 我必须调用fork来创建一个子进程来执行输入的命令,然
fork
、exec
和wait
,我已经阅读了它们,但这对我的处境仍然没有真正的帮助。
我要做的是:
打印promt并等待用户输入最多包含四个参数或选项的命令。“退出”将停止程序
一些示例,mkdir blah
,创建目录,然后提示输入新命令,touch blah/this blah/that blah/there
我必须调用fork
来创建一个子进程来执行输入的命令,然后在子进程中调用exec
,使子进程成为要执行的程序(这一部分让我更加困惑),最后在父进程中调用wait
,以便解释器在命令完成之前不会打印下一个提示
实现这一目标的最佳方式是什么?与中一样,读入命令/参数/选项然后执行它们的最佳方式是什么?
我认为这样做最好是do..while
,而while
条件是检查“退出”的条件
我知道,我做的很少,但也不多
int main()
{
char command[25];
pid_t pid;
int rs;
cout << "Enter command: ";
cin >> command;
while(strcmp(command, "exit") != 0) {
pid = fork();
if (pid == 0) { //child process
rs = execl("echo", command);
}
else { // parent process
cout << "Enter a command: ";
cin >> command;
}
}
return 0;
}
intmain()
{
char命令[25];
pid_t pid;
int-rs;
cout>命令;
while(strcmp(命令,“退出”)!=0){
pid=fork();
如果(pid==0){//子进程
rs=execl(“echo”,命令);
}
else{//父进程
cout>命令;
}
}
返回0;
}
这些系统调用的功能的一般分解:
分叉:分叉当前进程。实际上,当调用fork时,执行在调用fork时暂停,整个程序被复制到一个新的进程空间中,该进程空间是原始进程的子进程空间。然后这两个进程在fork调用之后继续并行执行。您需要获取PID,以便判断当前正在执行的程序是子程序还是父程序
exec:暂停当前进程的执行,用指定的要运行的新程序擦除内存中的当前进程。然后它运行新程序
等待:暂停当前进程,直到至少一个子进程终止。它是waitpid()的包装器,允许您暂停当前进程的执行,并等待当前进程的子进程(可能是自身的克隆,也可能是exec插入的新程序)的状态发生变化
下面是我在大学上过的一门课中的一些代码演示,正在等待和分叉(但没有执行):
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
const int BUFFER_SIZE = 1000;
void copySegment(int i, int segmentSize, FILE * fin, FILE * fout) {
// Does not need to be shown to prove point
}
int main(int argc, char * argv[]) {
int i;
sem_t * sem;
pid_t pid;
FILE * fin, * fout;
struct stat sbuf;
int fileSize, fileDescriptor, segmentSize;
fin = fopen(argv[1], "r");
fout = fopen("forkcopy.txt", "w");
fileDescriptor = fileno(fin);
fstat(fileDescriptor, &sbuf);
fileSize = sbuf.st_size;
segmentSize = fileSize / 4;
sem = sem_open("sem", O_CREAT | O_EXCL, 0644, 4);
sem_unlink("sem");
for (i = 0; i < 4; i++) {
pid = fork();
if (pid < 0)
printf("Fork error.\n");
else if (pid == 0)
break;
}
if (pid != 0) {
while (pid = waitpid(-1, NULL, 0)) {
if (errno == ECHILD)
break;
}
sem_destroy(sem);
fclose(fin);
fclose(fout);
exit(0);
} else {
sem_wait(sem);
copySegment(i, segmentSize, fin, fout);
sem_post(sem);
exit(0);
}
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
const int BUFFER_SIZE=1000;
无效复制段(int i,int segmentSize,文件*fin,文件*fout){
//不需要显示来证明这一点
}
int main(int argc,char*argv[]){
int i;
sem_t*sem;
pid_t pid;
文件*fin,*fout;
结构统计sbuf;
int fileSize、fileDescriptor、segmentSize;
fin=fopen(argv[1],“r”);
fout=fopen(“forkcopy.txt”,“w”);
fileDescriptor=fileno(fin);
fstat(文件描述符和sbuf);
fileSize=sbuf.st_size;
分段大小=文件大小/4;
sem=sem_open(“sem”,O|u CREAT | O|u EXCL,0644,4);
sem_取消链接(“sem”);
对于(i=0;i<4;i++){
pid=fork();
if(pid<0)
printf(“Fork错误。\n”);
否则如果(pid==0)
打破
}
如果(pid!=0){
while(pid=waitpid(-1,NULL,0)){
if(errno==ECHILD)
打破
}
扫描电镜(sem);
财务总监(财务);
fclose(fout);
出口(0);
}否则{
sem_wait(sem);
复制段(i、段大小、尾翼、尾翼);
sem_post(sem);
出口(0);
}
}
manfork
甚至还有代码示例。非常感谢您提供您的尝试。代码比您提出的关于最佳方法的问题更容易、更精确地提出改进建议。