System()调用C ++及其在编程中的angular色

我经常听说使用system("PAUSE")是不好的做法,而是使用std::cin.get()来代替。 现在我对系统调用的理解是,他们把一个stringinput到系统命令行并和操作系统通话,所以PAUSE是一个DOS命令,它在命令窗口中暂停输出。 我认为这与Mac和unix具有不同的关键字,并且由于缺乏跨OS兼容性而不鼓励使用系统调用。 (如果我有任何错误,请纠正我)

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

system("PAUSE")肯定不理想。 使用系统调用创建一个子进程,在Windows上是相当昂贵的,在任何情况下,在任何操作系统上都不便宜。 在嵌入式系统上,内存开销很大。

如果有什么办法可以做到这一点,没有太多的痛苦,然后做到这一点。 在等待用户按下单个按钮的情况下,cin.get()将很难被击败。 在这种情况下,你的应用程序进程只会阻塞在stdin上,只能设置内核可见的几个标志,最重要的是,不分配新的内存,不会创建新的调度实体,甚至不会创建中断处理程序。

另外,它和所有的c ++编译器在所有操作系统上的工作方式是一样的,因为它只使用一个非常标准的语言部分的基本特性,而不依赖于操作系统提供的任何东西。

编辑:预测你的担心,不要紧,如果它是昂贵的,因为整个想法是暂停。 那么,首先,如果它的价格昂贵的话,那么就会损害其他可能发生的性能。 当有一个应用程序正在启动时,有没有注意到(在Windows上),另外,已经打开的应用程序也变得不太敏感了? 另外,你的用户可能不是一个活的人,而是代表一个人类用户(也就是一个shell脚本)工作的另一个程序。 该脚本已经知道下一步该怎么做,并可以预先填充一个字符的标准输入,以跳过等待。 如果你在这里使用了一个子进程,那么这个脚本会经历一个(对人类来说是显而易见的)延迟。 如果脚本执行数百次(或数亿次),则可能需要几秒钟才能运行的脚本需要几天或几年的时间。

编辑2:什么时候使用system() :当你需要做另一个进程所做的事时,你不能轻易做到。 system()并不总是最好的选择,因为它有两个有点限制的事情。 首先,与子进程通信的唯一方法是通过命令行参数作为输入和返回值作为输出。 第二个是父进程阻塞,直到子进程完成。 这两个因素限制了系统可用的情况。

在unixy系统中,大多数子进程都是在fork发生的,因为它允许相同的程序在两个独立进程的相同位置继续运行,一个作为另一个进程的子进程(除非从操作系统请求它,否则几乎不可见)。 在Linux上,这是特别优化的,大约和创建pthread一样便宜。 即使在这个速度不快的系统上,它仍然是非常有用的(如apache进程池方法所示)(在windows上不可用/ 链接到unix文档 )

其他情况下(在Windows上也是如此!)通常由popenexec系列函数处理。 popen创建一个子popen和一个全新的管道,连接到子popen的stdin或stdout。 父进程和子进程可以并发运行,并且可以很容易地进行通信。 ( 链接到Windows文档 / 链接到Unix文档 )

exec *系列函数(有几个,execl,execv等)导致当前程序被新程序替换。 原始程序无形地退出,新的程序接管。 当新进程返回时,它将返回到原来的进程,就好像那个进程已经在那个时候返回了,而不是消失。 exit(system("command"))的优点是没有新的进程创建,节省时间和内存(虽然不总是非常多)( 链接到Windows文档 / 链接到UNIX文档 )

system可以合理地被某些脚本工具用来调用某些配方动作中的几个步骤。 例如,某个程序可以使用system调用文本编辑器来编辑一些配置文件。 它不必过多地关心发生了什么事情,而是应该等到用户保存并关闭编辑器才能继续。 然后,它可以使用返回值来确定编辑会话是否成功,因为编辑器实际上打开了所请求的文件(编辑器本身就存在!),但会从中读取会话的实际结果直接编辑文件,而不是与子进程通信。 ( 链接到Windows文档 / 链接到Unix文档 )

系统调用被发送到操作系统的shell或者命令行解释器(dos,bash等等),并且直到shell执行它想要的命令。

您将避免使用这些类型的调用,因为这会降低程序的可移植性,以便与其他操作系统一起使用。 我只会认为,只有当你确定你的代码是针对特定的操作系统,你应该使用这种调用。

但是我的问题是:什么时候使用system()调用是适当的? 他们应该如何应用?

当你不能做你想用自己的代码或图书馆做的事情(或者实施它的成本大于启动新流程的成本)。 与cin.get()相比,system()在系统资源方面相当昂贵,因此它只能在绝对必要时使用。 请记住system()通常会启动一个完整的新shell以及您要求它运行的任何程序,这样就会启动两个新的可执行文件。

顺便说一下, 系统()调用不应该用于设置了SUIDSGID位的二进制文件,从手册页引用:

不要使用具有set-user-ID或set-group-ID特权的程序使用system(),因为可能会使用某些环境变量的奇怪值来颠覆系统完整性。 使用exec(3)函数系列,而不是execlp(3)或execvp(3)。 实际上,system /()不能在/ bin / sh是bash版本2的系统上使用set-user-ID或set-group-ID权限的程序正常工作,因为bash 2在启动时会丢弃权限。

就我所知,系统(“PAUSE”)只是一个窗口,这就是为什么它被折磨的原因。

system()用于请求操作系统运行一个程序。

为什么你的程序需要操作系统运行一个程序? 那么有案子。 有时外部程序或操作系统命令可以执行在您自己的程序中很难执行的任务。 例如,外部程序可以使用提升的权限或访问权限数据格式来操作。

system()函数本身是相当便携的,但是通过它的命令字符串很可能是特定于平台的 – 尽管命令字符串可以从本地配置数据中提取出来,以使其更加与平台无关。

fork()exec*()spawn*()CreateProcess()等其他函数将使您对运行外部程序的方式有更多的控制,但是是特定于平台的,并且可能无法在您选择的平台上。

system("PAUSE")是一个旧的DOS技巧,现在通常被认为是相当糟糕的风格。