草庐IT

c++ - 用不克隆进程内存的调用替换 system 和 popen 调用

coder 2024-02-23 原文

我正在编写宽度内存和性能敏感的多线程服务器。因此,我需要不使用 fork() 的标准 system()popen() 调用的替代方法,它克隆了所有进程内存通常需要太多时间。

看来,需要使用 vfork() 然后 execve() 来实现。

谁能帮我解决两个问题:

  • 替换 system() 调用。 行为示例:一个线程调用要执行的函数,例如 touch filename 并调用线程等待直到执行结束。 (所有其他线程必须继续工作)
  • 替换 popen() 调用 行为示例: 相同的行为,但需要获取命令的输出,例如 ls -flags(此代码的替代:Correct Code - Non-blocking pipe with popen)

谢谢

最佳答案

这只是关于如何处理您提出的解决方案的建议。对于您询问的两个具体操作:

  • touch:可以通过打开和关闭要触摸的文件来实现类似的效果
    • 注意不要在open 上使用O_TRUNC 标志
  • ls:有点痛苦,因为你需要在 POSIX 系统上使用 dirent.h,然后遍历结果
    • opendir
    • readdir
    • 确保在完成后调用closedir

如果您想使用 vforksystempopen 调用替换为等效的调用,则需要注意一些问题。 vfork 调用使用起来有点棘手,因为如果子进程在调用后立即执行 exec 以外的任何操作,您就有可能破坏父进程的内存状态.

对于系统的替换:

  • 创建一个辅助程序来执行参数中提供的字符串
    • 辅助程序可以在提供的参数上调用system,或者解析命令字符串并调用exec
  • 在您的 system 替换函数中,创建一个 arg vector 来调用辅助程序,并将您真正想要执行的程序字符串作为参数传递给该程序
  • 调用vfork后,立即exec子程序中的辅助程序
  • parent 等待 child 完成

在您的 popen 替换中:

  • 创建一个辅助程序,它接受stdoutstdin 文件描述符作为参数,以及您要执行的命令的字符串
    • 辅助程序会将传入的描述符复制为参数指示的01(或两者)
    • 辅助程序可以通过popen和父子之间的代理数据执行字符串,也可以在解析命令字符串后调用exec
  • 在您的 popen 替换函数中,使用 pipe 创建 stdoutstdin 通信 channel (根据第二个 popen 函数参数)并创建一个 arg vector 来调用帮助程序,传入适当的文件描述符编号和命令字符串作为参数
  • 调用vfork后,立即exec子程序中的辅助程序
  • 您需要一个 pclose 替换来获取子进程

关于c++ - 用不克隆进程内存的调用替换 system 和 popen 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10987563/

有关c++ - 用不克隆进程内存的调用替换 system 和 popen 调用的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  4. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  5. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  6. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  7. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  8. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  9. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  10. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

随机推荐