c++ - C++中的System()调用及其在编程中的作用

标签 c++ windows operating-system system dos

我经常听到使用system("PAUSE")是不好的做法,而改为使用std::cin.get()。现在,我对系统调用的理解是,它们采用一个字符串,然后将其输入系统命令行并与OS进行通讯,因此PAUSE是一种DOS命令,可在命令窗口中暂停输出。我认为这与Mac和unix具有不同关键字的方法类似,并且由于缺乏跨OS兼容性,不建议使用系统调用。 (如果我对此有任何误解,请纠正我)

我的问题是:什么时候使用system()调用合适?应该如何应用它们?什么时候不应该使用它们?

最佳答案

system("PAUSE")当然不理想。使用对系统的调用会创建一个子进程,该子进程在Windows上相当昂贵,无论如何在任何操作系统上都不是很便宜。在嵌入式系统上,内存开销非常大。

如果有什么办法可以做到而又没有很多痛苦,那就动手做吧。在等待用户按下单个按钮的情况下,cin.get()很难被击败。在这种情况下,您的应用程序进程将仅在stdin上阻塞,仅设置几个对内核可见的标志,并且最重要的是,不分配任何新内存,也不创建新的调度实体,甚至不创建中断处理程序。

另外,由于它仅使用语言的非常标准部分的非常基本的功能,而不依赖于操作系统提供的任何功能,因此在所有使用c++编译器的操作系统上都可以使用相同的功能。

编辑:预测您的担心,它是否昂贵并不重要,因为整个想法都在暂停。好吧,首先,如果价格昂贵,那么它可能会损害其他方面的性能。是否曾经在一个应用程序启动时(在Windows上)注意到,而其他已经打开的应用程序启动时的响应速度也变慢了吗?此外,您的用户可能不是真实的人,而是另一个代表实际用户工作的程序(例如,shell脚本)。该脚本已经知道下一步该怎么做,并且可以用一个字符预填充stdin来跳过等待。如果您在此处使用了子流程,则该脚本将经历一个(很容易注意到的)延迟。如果脚本执行了数百次(或数亿次!),那么可能需要几秒钟才能运行的脚本现在需要几天或几年的时间。

EDIT2:何时使用system():当您需要执行其他进程要执行的操作时,就很难做到。 system()并不总是最好的候选者,因为它做了两件事,但有些局限性。首先,与子流程进行通信的唯一方法是使用命令行参数作为输入,并使用返回值作为输出。第二个是父进程将阻塞直到子进程完成。这两个因素限制了系统可用的情况。

在unixy系统上,大多数子进程都使用fork进行操作,因为它允许同一程序在两个单独的进程的同一位置继续运行,一个作为另一个进程的子进程(除非您从OS要求,否则很难注意到)。在Linux上,它经过特别优化,并且与创建pthread一样便宜。即使在速度不那么快的系统上,它仍然非常有用(如apache进程池方法论所证明)(在Windows/link to unix docs上不可用)

其他情况(在Windows上也是如此!)通常由popenexec系列函数处理。 popen创建一个子进程和一个连接到子进程的stdin或stdout的全新管道。然后,父进程和子进程都可以同时运行,并且通信非常容易。 (link to windows docs/link to unix docs)

另一方面,exec *函数系列(有多个,execl,execv等)导致当前程序被新程序替换。原始程序将隐式退出,新进程将接管工作。然后,当新进程返回时,它将返回到称为原始进程的任何位置,就像该进程在那时已返回而不是消失一样。与exit(system("command"))相比,此方法的优点是无需创建新进程,从而节省了时间和内存(尽管并不总是那么多)(link to windows docs/link to unix docs)

某些脚本化工具可能会使用system来调用某些配方操作中的多个步骤。例如,在某个时候,程序可以使用system调用文本编辑器来编辑某些配置文件。它不需要过多关注发生的事情,但是它一定要等到用户保存并关闭编辑器后再继续。然后,它可以使用返回值来确定编辑 session 是否成功,这意味着编辑器实际上已打开了所请求的文件(并且编辑器本身已经存在!),但将从中读取 session 的实际结果。直接编辑的文件,而不是与子流程进行通信。 (link to windows docs/link to unix docs)

关于c++ - C++中的System()调用及其在编程中的作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/900666/

相关文章:

c++ - 如何在 C++ 中将数组中的所有元素初始化为相同的数字

c++ - 如何在 Scintilla 中设置边距蒙版?

javascript - 通过 IE 单点登录

java - 如何将 .jar 转换为 .exe?

python - 从 Assembly 执行 python 脚本

c++ - 用户空间栈和堆的内存布局

c++ - 将纬度/经度转换为 X/Y 坐标

c++ - std::function 可以有函数指针作为类型吗?

windows - 使用 PowerShell Direct 时,通过 psexec 打开的窗口为空白,但当 psexec 本地启动时,窗口正常

operating-system - 现代操作系统是否使用 MCFG ACPI 表来查找 xHCI 的寄存器?