了解 C++ 中的 fork、exec 和 wait (Linux)
Understanding fork, exec, and wait in C++ (Linux)
我对在 linux 中使用这些不同类型的系统调用还很陌生,这让我很困惑。有了这个,我只要求推动正确的 direction/a 开始,而不是完成。
使用 fork
、exec
和 wait
,我已经阅读了它们,但这对我的情况仍然没有真正帮助。
我要做的是以下,
打印提示并等待用户输入最多包含四个参数或选项的命令。 “退出”将停止程序。
一些示例,mkdir blah
,创建目录,然后提示输入新命令,touch blah/this blah/that blah/there
。
我要调用fork
创建一个子进程来执行输入的命令,然后在子进程中调用exec
让子进程成为要执行的程序(这个部分让我更加困惑),最后在父进程中调用 wait
以便解释器在命令完成之前不会打印下一个提示。
完成此任务的最佳方法是什么?比如,读取 command/arguments/options 然后执行它们的最佳方法是什么?
我认为这样做会更好是 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;
}
每个系统调用的一般分类:
fork:fork当前进程。从字面上看,当调用 fork 时,执行会在调用 fork 时暂停,整个程序被复制到一个新进程 space 中,它是原始进程的子进程。然后两个进程在 fork 调用之后继续并行执行。您需要获取 PID 才能判断当前正在执行的程序是子程序还是父程序。
exec:暂停当前进程的执行,用指定的新程序擦除内存中的当前进程到运行。然后 运行 改为新程序。
wait:暂停当前进程,直到至少一个子进程终止。它是 waitpid() 的包装器,允许您暂停当前进程的执行并等待当前进程的子进程状态发生变化(可能是自身的克隆或由 [= 换入的新程序) 21=]执行)
这里有一些演示等待和分叉(但没有执行)的代码,来自 class 我在大学学习的课程:
#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);
}
}
我对在 linux 中使用这些不同类型的系统调用还很陌生,这让我很困惑。有了这个,我只要求推动正确的 direction/a 开始,而不是完成。
使用 fork
、exec
和 wait
,我已经阅读了它们,但这对我的情况仍然没有真正帮助。
我要做的是以下,
打印提示并等待用户输入最多包含四个参数或选项的命令。 “退出”将停止程序。
一些示例,mkdir blah
,创建目录,然后提示输入新命令,touch blah/this blah/that blah/there
。
我要调用fork
创建一个子进程来执行输入的命令,然后在子进程中调用exec
让子进程成为要执行的程序(这个部分让我更加困惑),最后在父进程中调用 wait
以便解释器在命令完成之前不会打印下一个提示。
完成此任务的最佳方法是什么?比如,读取 command/arguments/options 然后执行它们的最佳方法是什么?
我认为这样做会更好是 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;
}
每个系统调用的一般分类:
fork:fork当前进程。从字面上看,当调用 fork 时,执行会在调用 fork 时暂停,整个程序被复制到一个新进程 space 中,它是原始进程的子进程。然后两个进程在 fork 调用之后继续并行执行。您需要获取 PID 才能判断当前正在执行的程序是子程序还是父程序。
exec:暂停当前进程的执行,用指定的新程序擦除内存中的当前进程到运行。然后 运行 改为新程序。
wait:暂停当前进程,直到至少一个子进程终止。它是 waitpid() 的包装器,允许您暂停当前进程的执行并等待当前进程的子进程状态发生变化(可能是自身的克隆或由 [= 换入的新程序) 21=]执行)
这里有一些演示等待和分叉(但没有执行)的代码,来自 class 我在大学学习的课程:
#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);
}
}