【问题标题】:Is using popen() in C/C++ is a bad coding practise?在 C/C++ 中使用 popen() 是一种不好的编码习惯吗?
【发布时间】:2017-09-18 04:14:05
【问题描述】:

我想更改 Linux 系统的时区。我知道有很多方法。 一种方法是使用 tzset() 函数,另一种方法是从 'popen()' 函数调用 'timedatectl' 命令。 我正在使用第二种方法,即使用“popen()”。

我只想问在你的代码中使用“popen()”是一种好的编程习惯吗?

另外,我小心地为每个“popen()”调用“pclose()”。

【问题讨论】:

  • 它是 C 或 C++,请选择一个。
  • 如果有一个函数调用来完成这项工作,我宁愿在生成新进程之前使用它,如果没有,使用popen 没有任何问题。使用函数调用进行错误处理通常更容易,如果函数调用丢失或错误,您很可能会遇到编译时错误。 IMO:这并不总是不好的做法,但在您的特殊情况下确实如此。
  • 问这样的问题意味着您已经尝试了一些东西,但您发现出了问题或可能会出错。如果是这样,问题究竟出在哪里?
  • 使用 popen 是不错的做法,除非您知道自己想要实现什么。我已经看到了一些使用 popen 对文件进行分类并在其中搜索字符串的代码。这可以通过使用文件读取和搜索字符串来实现。
  • @GillBates 您认为 C++ 与 C 的答案会有所不同吗? C++ 的标准库中是否有更好的popen()

标签: c++ linux unix timezone


【解决方案1】:

一般来说popen 没有任何问题,如果您确实需要一个子进程来为您完成特定的工作。

popen 创建一个管道,允许您读取子进程的输出(它写入标准输出的内容)或将输入写入其标准输入 - 但不能同时进行。

如果您对任一选项都不感兴趣,您可能更愿意调用system(不过,system 将等待进程终止,而 popen - pclose 则等待)。

但是,如果您可以通过简单地调用普通函数(系统调用与否)来完成相同的工作,为什么还要创建一个单独的进程呢?然后,您使用进程会产生大量开销(进程必须初始化并连接到操作系统,它需要自己的内存来存储可执行代码、堆和堆栈......)!

如果有问题的工作需要相当长的时间并且您不能等待功能完成,但需要做一些其他事情,它会变得有点复杂。但是,在这种情况下,我宁愿只创建一个 thread 并再次从那里调用该函数...

【讨论】:

  • 我同意。但我认为如果我的任务是“小”并且可以使用更少的代码快速使用“popen()”来完成。为什么我应该浪费时间编写冗长而复杂的代码。最后,它给了我相同的输出。显然,我的观点可能是错误的。有什么指导吗?
  • @sonugupta 好吧,快速和肮脏代码和生产代码之间的区别......如果您需要一些“使用一次,之后就扔掉”的工具,您可以节省您的时间...如果您正在编写富有成效的代码 - 请正确执行!
  • @sonugupta(虽然我个人更喜欢为我自己的个人使用工具编写适当的代码......)
  • 感谢您的指导。我一定会遵循同样的做法。
【解决方案2】:

popen() 调用一个 shell 来运行命令,这是一个额外的不必要的间接层。此外,还有各种各样的安全隐患,例如,您无法控制环境 - 或者实际调用了哪个 shell。

我会说它对于原型和概念证明很好,但对于生产代码,您应该使用fork(),它是 IO 的执行和管道之一。

编辑

如果有一个函数相当于通过调用命令来做某事,请始终先使用它。例如,如果您可以使用 tzset() 实现您想要的,请始终使用它而不是生成一个新进程。

【讨论】:

  • 如果我错了,请纠正我,您是说要为生产代码执行此操作。 'pid_t pID = fork(); if(pID == 0) { //popen() 东西 }'
  • 这要复杂得多。您必须为标准输入和标准输出创建管道,然后分叉,然后用管道和执行程序替换子项中的标准输入和标准输出。父母必须将需要的内容放在标准输入上并从标准输出中读取需要的内容,然后等待孩子退出并读取其退出状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-11
  • 2013-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多