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

2024-01-18

我对在 Linux 中使用这些不同类型的系统调用非常陌生,这让我很困惑。就此而言,我只是要求朝着正确的方向推动/开始,而不是要求完成。 使用fork, exec, and wait,我已经阅读了它们,但这仍然对我的情况没有真正帮助。 我要做的是以下,

打印提示并等待用户输入最多包含四个参数或选项的命令。 “exit”将停止程序。

一些例子,mkdir blah,创建目录,然后提示输入新命令,touch blah/this blah/that blah/there.

我得打电话fork创建一个子进程来执行输入的命令,然后调用exec在子进程中使子进程成为要执行的程序(这部分让我更困惑),最后调用wait在父进程中,以便解释器在命令完成之前不会打印下一个提示。

实现这一目标的最佳方法是什么?例如,读取命令/参数/选项然后执行它们的最佳方法是什么? 我认为这样做会更好do..whilewhile条件是检查“退出”的条件

我知道我所做的很少,也不算多。

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 调用之后立即继续并行执行。您需要获取 PID 才能判断当前正在执行的程序是子程序还是父程序。

exec:暂停当前进程的执行,用指定的新程序擦除内存中的当前进程以运行。然后它会运行新程序。

wait:挂起当前进程,直到至少一个子进程终止。它是 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);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解 C++ 中的 fork、exec 和 wait (Linux) 的相关文章

随机推荐

  • 从 bash 执行 php 脚本时出错

    你好 我正在尝试从 bash 脚本执行 php 文件 bin sh php func php and func php文件看起来像
  • 悬停效果不会在图像上触发

    我将鼠标悬停在 picutre div 中的 img 上时遇到问题 HTML div img class content pic src image exemple jpg alt exemple img class content pic
  • Apple 推送服务证书不受信任

    我最近在我的 M1 mac mini 上创建了 Apple Push Service 证书 在钥匙串中 它表示证书不受信任 我已经安装了开发者关系中级证书 如中所述here https developer apple com forums
  • Ajax字符串长度限制?

    ajax 的 url 中添加的参数长度是否有限制 我在 Ruby 上使用 Thin 服务器 并以以下格式从 Web 浏览器发出 ajax 请求 io new XMLHttpRequest io open GET http localhost
  • 使用UsageStatsManager获取前台应用程序

    我正在尝试使用UsageStatsManager 来获取带有Marshmallow 的Nexus 5 上的前台应用程序 我记得它曾经有效 但由于某种原因 我现在得到包 类名称的空字符串 这是我的实现 public String getFor
  • ffmpeg - 制作干净的 WAV 文件

    我希望使用以下命令将多个文件批量转换为音频文件ffmpeg对于一个名为Star Wars Jedi Knight Dark Forces II 我遇到的问题是ffmpeg似乎正在做一些事情Jedi Knight无法播放声音文件 Jedi K
  • .htaccess 路径只能通过 ip 访问

    我想使用 htaccess 配置阻止来自我的站点的路径 这个想法是只有一组特定的 IP 可以从 URL 访问该特定路径 Note 它是一个路径 而不是页面或目录 我们正在尝试屏蔽 Web 服务 以便仅对 URL 进行后调用 我想要网址exa
  • IntelliJ 抑制 API 方法的未使用警告

    我最近从 Eclipse 切换到 IntelliJ IDEA 我真的很喜欢检查器 发现它们用警告来标记潜在的错误 对我来说非常有用 我遇到了一个我无法解决的问题 我有一些Java项目在其他项目中用作API 因此它包含未使用的方法 这些方法被
  • 如何在nodejs中使用geoNear?

    我想使用地理空间geoNear mongodb中的数据库 Mongo查询 db runCommand geoNear tmp near type Point coordinates 77 00000 12 00000 spherical t
  • ELF可执行文件的起点?

    我用 anjuta 在 lubuntu 12 10 上编译以下 C 程序 int main return 0 文件名是 foobar 然后我打开终端并写入命令 ndisasm foobar b 32 1 gt asm txt 使用32位指令
  • Tranquility服务器不会向druid发送数据

    我在用着imply 2 2 3 这是我的宁静服务器配置 dataSources spec dataSchema dataSource tutorial tranquility server parser type string parseS
  • TCL 的通用字符串引用

    我正在编写一个实用程序 恰好是在 python 中 它以 TCL 脚本的形式生成输出 给定 python 中的一些任意字符串变量 不是 unicode 我想生成一个 TCL 行 例如 set s something 这将设置 TCL 变量
  • 过滤magento订单集合

    我使用以下行从 magento 加载订单集合 Load Order Collection order collection Mage getModel sales order gt getCollection 如何过滤此集合以忽略状态为 已
  • 如何通过“manage.py shell”使用交互式解释器重新加载 Django 模型模块?

    我知道如何在常规 Python 解释器会话中重新加载常规 Python 模块 这个问题记录了如何很好地做到这一点 如何卸载 重新加载 Python 模块 https stackoverflow com questions 437589 ho
  • 如何在 WiX 4 中使用 HarvestDirectory

    我尝试在 WiX 4 Preview 1 中使用 HarvestDirectory 项目元素 但发现它非常不直观 尽管我遵循文档中的面包屑 但我似乎无法让它真正执行任何明显的操作 在 WiX 3 中 我直接使用命令行工具 并且可以通过这种方
  • 在 Kotlin 中写入等于 Int.MIN_VALUE 的十六进制整数文字

    如何编写等于的十六进制整数文字Int MIN VALUE 这是 2147483648十进制 在 Kotlin 中 AFAIK 一个 Int 是 4 个字节 有时看起来像2的补码 https en wikipedia org wiki Two
  • WSO2 EMM Android 代理配置

    我正在尝试使用WSO2 EMM service 我下载了二进制文件并将其上传到我的服务器并在其中配置了 IP 地址 然后 我开始了 是的 效果很好 这是我的地址 a href https ip 94433 emm 普通管理员管理员 但是 我
  • GCC 不再实现

    我必须将此代码片段从 varargs h 更改为 stdarg h 但我不知道具体如何 ifndef lint int ll log va alist va dcl int event result LLog lp va list ap v
  • 如何访问 Windows 8.1 商店应用程序中 SubSections 内的控件?在视觉树中搜索不起作用

    我正在开发 Win8 1 应用程序 主页使用 Hub 在每个 HubSection 中 我需要从代码访问不同的控件 HubSection 的内容不是直接定义的 而是由 DataTemplate 定义的 因此 无法通过 x Name 访问内容
  • 了解 C++ 中的 fork、exec 和 wait (Linux)

    我对在 Linux 中使用这些不同类型的系统调用非常陌生 这让我很困惑 就此而言 我只是要求朝着正确的方向推动 开始 而不是要求完成 使用fork exec and wait 我已经阅读了它们 但这仍然对我的情况没有真正帮助 我要做的是以下