简体   繁体   English

了解C ++中的fork,exec和wait(Linux)

[英]Understanding fork, exec, and wait in C++ (Linux)

I'm very new to using these different types of system calls in linux, Which led me to much confusion. 我对在Linux中使用这些不同类型的系统调用非常陌生,这使我感到非常困惑。 With this, I am only asking for a push in the right direction/a start, not for a completion. 这样,我只是要求朝着正确的方向/开始,而不是要求完成。 Using fork , exec , and wait , I have read up on them, but that still hasn't really helped me in my situation. 使用forkexecwait ,我已经阅读了它们,但是在我的情况下,这仍然没有真正帮助我。 What I have to do is the following, 我要做的是以下几点,

Print a promt and wait for the user to enter a command with up to four arguments or options. 打印一个promt,然后等待用户输入最多包含四个参数或选项的命令。 "exit" will stop the program. “退出”将停止程序。

Some examples, mkdir blah , creates the directory and then prompts for a new command, touch blah/this blah/that blah/there . 一些示例mkdir blah创建目录,然后提示输入新命令,请touch blah/this blah/that blah/there

I have to call fork to create a child process to execute the command entered, then call exec in the child process to make the child become the program that is to be executed (this part confuses me even more), and finally call wait in the parent process so that the interpreter doesn't print next prompt until command is finished. 我要叫fork创建一个子进程来执行输入的命令,然后调用exec在子进程使孩子成为被执行的程序(这部分让我困惑甚至更多),最后调用wait中父进程,以使解释器在命令完成之前不会打印下一个提示。

What would be the best way to accomplish this? 做到这一点的最佳方法是什么? As in, what's the best way to read in the command/arguments/options and then have them executed? 如上,读取命令/参数/选项然后执行它们的最佳方法是什么? I would assume it would be better to do this is a do..while with the while condition being what checks for "exit" 我会假设它会更好做,这是一个do..whilewhile条件是用于“退出”什么检查

What little I have done, which isn't much, I know. 我知道我做了什么,没什么。

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;
}

A general breakdown of what each of those system calls do: 这些系统调用各自的功能的一般细分:

fork : Forks the current process. fork分叉当前进程。 Literally when fork is called, execution is paused at the call to fork, and the entire program is copied into a new process space that is a child of the original. 从字面上看,当调用fork时,执行将在调用fork时暂停,并将整个程序复制到一个新的进程空间中,该空间是原始进程的子级。 Then both processes continue execution from right after the fork call in parallel. 然后,两个进程在fork并行调用之后立即继续执行。 You'll need to get the PID in order to tell if the program that is currently being executed is the child or parent. 您需要获取PID才能判断当前正在执行的程序是子进程还是父进程。

exec : Pauses execution of current process, wipes over the current process in memory with the designated new program to run. exec :暂停当前进程的执行,使用指定的要运行的新程序擦除内存中的当前进程。 It then runs the new program instead. 然后,它将运行新程序。

wait : Suspends the current process until at least one child process terminates. wait :暂停当前进程,直到至少一个子进程终止。 It is a wrapper around waitpid() which allows you to pause the current process's execution and wait for a change in the state of a child process of the current process (which may be a clone of itself or a new program swapped in by exec ) 它是waitpid()的包装,它使您可以暂停当前进程的执行,并等待当前进程的子进程的状态更改(它可以是其自身的克隆,也可以是exec交换的新程序)。

Here is some code demoing waiting and forking (but no exec) from a class I took at University: 这是我在大学上的一堂课的一些演示代码,演示了等待和分叉(但没有执行):

#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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM