Go 是否可以在不为每个外部进程启动一个操作系统线程的情况下生成并与外部进程通信?

2023-12-24

简洁版本:

Golang 是否可以生成多个外部进程(shell 命令)在平行下,这样它就不会启动一个操作系统线程每个外部进程......并且在完成后仍然能够接收其输出?

更长的版本:

在 Elixir 中,如果使用端口,则可以生成数千个外部进程,而无需真正增加 Erlang 虚拟机中的线程数量。

例如。下面的代码片段,启动了2500个外部sleep进程,仅由 20 个进程管理操作系统线程在 Erlang 虚拟机下:

defmodule Exmultiproc do
  for _ <- 1..2500 do
    cmd = "sleep 3600"
    IO.puts "Starting another process ..."
    Port.open({:spawn, cmd}, [:exit_status, :stderr_to_stdout])
  end
  System.cmd("sleep", ["3600"])
end

(前提是你设置了ulimit -n到一个较高的数字,例如 10000)

另一方面,Go 中的以下代码应该做同样的事情 - 启动 2500 个外部sleep进程 - 也启动 2500操作系统线程。所以它显然开始了一个操作系统线程每个(阻塞?)系统调用(以免阻塞整个CPU,或类似的,如果我理解正确的话):

package main

import (
    "fmt"
    "os/exec"
    "sync"
)

func main() {
    wg := new(sync.WaitGroup)
    for i := 0; i < 2500; i++ {
        wg.Add(1)
        go func(i int) {
            fmt.Println("Starting sleep ", i, "...")
            cmd := exec.Command("sleep", "3600")
            _, err := cmd.Output()
            if err != nil {
                panic(err)
            }
            fmt.Println("Finishing sleep ", i, "...")
            wg.Done()
        }(i)
    }
    fmt.Println("Waiting for WaitGroup ...")
    wg.Wait()
    fmt.Println("WaitGroup finished!")
}

因此,我想知道是否有一种方法可以编写 Go 代码,使其执行与 Elixir 代码类似的操作,而不是打开一个操作系统线程每个外部进程?

我基本上正在寻找一种方法来管理至少几千个外部长时间运行(最多 10 天)的进程,以一种尽可能减少操作系统中任何虚拟或物理限制的问题的方式。

(对于代码中的任何错误,我深表歉意,因为我是 Elixir 的新手,而且也是 Go 的新手。我渴望了解我所犯的任何错误。)

编辑:澄清了并行运行长时间运行的进程的要求。


我发现如果我们不wait进程,Go运行时将不会启动2500 operating system threads。所以请使用 cmd.Start() 而不是 cmd.Output()。

但似乎无法读取进程的stdout无需通过 golang os 包消耗操作系统线程。我认为这是因为 os 包不使用非块 io 来读取管道。

下面的底部程序在我的 Linux 上运行良好,尽管它阻止了进程的标准输出,正如 @JimB 在评论中所说,也许是因为我们的输出很小并且适合系统缓冲区。

func main() {
    concurrentProcessCount := 50
    wtChan := make(chan *result, concurrentProcessCount)
    for i := 0; i < concurrentProcessCount; i++ {
        go func(i int) {
            fmt.Println("Starting process ", i, "...")
            cmd := exec.Command("bash", "-c", "for i in 1 2 3 4 5; do echo to sleep $i seconds;sleep $i;echo done;done;")
            outPipe,_ := cmd.StdoutPipe()
            err := cmd.Start()
            if err != nil {
                panic(err)
            }
            <-time.Tick(time.Second)
            fmt.Println("Finishing process ", i, "...")
            wtChan <- &result{cmd.Process, outPipe}
        }(i)
    }

    fmt.Println("root:",os.Getpid());

    waitDone := 0
    forLoop:
    for{
        select{
        case r:=<-wtChan:
            r.p.Wait()
            waitDone++
            output := &bytes.Buffer{}
            io.Copy(output, r.b)
            fmt.Println(waitDone, output.String())
            if waitDone == concurrentProcessCount{
                break forLoop
            }
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go 是否可以在不为每个外部进程启动一个操作系统线程的情况下生成并与外部进程通信? 的相关文章

  • Elixir:模式匹配对于元组和映射的工作方式不同

    在 Elixir 中 如果我尝试模式匹配以下两个元组 a 1 2 我收到匹配错误 但如果我对两张地图做同样的事情 x a x 1 y 2 它工作正常 并且a绑定到 1 我可以明白为什么匹配两个元组会出错 但为什么匹配映射不会出错 在第一个示
  • 如何从 golang fyne 容器中删除对象

    我正在开发 GUI 应用程序 需要动态添加和删除 gui 元素 我想知道是否有办法从 golang fyne 容器中删除元素 在下面的示例代码中 我创建了容器并动态添加元素 现在我希望能够删除这些元素而不是隐藏它们 我尝试的一个 解决方案
  • 为什么有时Task明显慢于Thread?

    我正在使用 MVVM 模式制作 WPF 应用程序 我发现有时任务明显慢于线程 例如 在测试 ViewModel 中 public void DoSomething Stopwatch stopwatch Stopwatch StartNew
  • 是否可以将 Go 代码作为脚本运行?

    随着Go正在成为 系统 的语言 我想知道是否可以将 Go 代码作为脚本运行而不编译它 有可能这样做吗 动机 因为有关于动机的问题 取自如何使用 Scala 作为脚本语言 http alvinalexander com scala how t
  • 记录 http.ResponseWriter 内容

    Premise 我发现了类似的问题 但不适用于我的情况 因此请不要将其标记为重复 我在 Go 中有一个 HTTP 服务器 并且创建了一个中间件记录请求 响应时间 我也想记录响应 我用过httputil DumpRequest在一个名为的函数
  • Interlocked 类可以安全地与 lock() 混合吗?

    当您将互锁操作与 lock 和其他更高级别的锁 混合使用时 是否可以保证原子读取 我对混合这样的锁定机制时的一般行为以及 Int32 和 Int64 之间的任何差异感兴趣 private Int64 count private object
  • dotNet:有没有办法在 UI 线程上执行 Join 语句?

    我正在编写一个简单的线程应用程序 当单击开始按钮时 应用程序禁用此按钮 运行 5 个线程 只需进行 For 迭代并更新 5 个进度条 最后一个线程正在等待线程结束 以重新启用我的开始按钮 问题 用户看到按钮在进度条达到 100 之前已启用
  • 需要多少个线程才能使它们成为错误的选择?

    我必须使用 boost thread 用 C 编写一个不太大的程序 当前的问题是处理大量 可能是数千或数万 数百和数百万也是可能的 数量 可能 的大文件 每个文件彼此独立 并且它们都驻留在同一目录中 我正在考虑使用多线程方法 但问题是 我应
  • Golang:使用像 Node.js 中那样的可读流从 PostgreSQL 数据库中选择几百万行

    我有大约 5000 万行的 PostgreSQL 表 我想编写 Go 代码来从该表中选择大约 100 万行 并以有效的方式处理它们 上次我使用了nodejs和这个NPM模块pg 查询流 https www npmjs com package
  • 为什么锁可以确保底层监视器被释放而直接使用监视器却不能?

    msdn 文章线程同步 C 编程指南 http msdn microsoft com en us library ms173179 28v vs 90 29 aspx规定 lock x DoSomething 相当于 System Obje
  • 在多核上运行 python 线程

    我知道Python 2 7不允许在不同的内核上运行多个线程 你需要使用multiprocessing模块以实现某种程度的并发性 我正在看concurrent futuresPython 3 4 中的模块 是否使用ThreadPoolExec
  • 防止使用 golang 服务器访问文件夹中的文件

    我在 golang 中有一个服务器可以处理这样的文件夹路径 fs http FileServer http Dir assets http Handle Images fs http ListenAndServe 8000 nil 但在这个
  • Git - 致命:无法获取当前工作目录?

    When I git clone从回购协议中 我得到 fatal Could not get current working directory No such file or directory 我该怎么办 我检查了服务器并发现 git文
  • 使用android应用程序类运行一个线程后台将一些数据发布到web服务

    我可以在 Android 的 Application 类中编写一个线程吗 该线程每五分钟运行一次 将数据发布到 Web 服务 public class MyApplication extends Application Override p
  • 多线程进程的线程ID可以与另一个正在运行的进程的进程ID相同吗?

    我正在尝试找到一种方法来唯一标识多进程环境中的线程 我有一个服务器 它跟踪连接到它的不同进程 其中一些是多线程的 一些不是 为了识别多线程连接中的线程 我使用线程 ID 作为唯一标识符 在任何给定时间最多有 1 个多线程进程连接 我的问题是
  • import java 导入错误:没有名为 java 的模块

    我似乎遇到了障碍 根本无法解决这个问题 任何人都可以帮我弄清楚为什么我无法导入 java 模块吗 Error Traceback most recent call last File datasource config py line 3
  • Ruby MRI 1.8.7 - 文件写入线程安全

    在我看来 在 Ruby MRI 1 8 7 中写入文件是完全线程安全的 示例 1 完美的结果 File open test txt a f threads 1 000 000 times do n threads lt lt Thread
  • 易失性数组 C++

    我有一个应用程序 它有一个指针数组MyObject对象 MyObject arr arr new MyObject 10 应用程序有两个线程 这些线程会创建和删除new MyObject 排列arr 所以arr n 会一直改变 但是MyOb
  • java多线程中“私有最终对象”锁定有什么用?

    java多线程中 私有最终对象 锁定有什么用 据我的理解 我认为要使一个类成为线程安全的 我们应该使用内部锁定 将所有方法标记为同步并使用 this 将它们锁定在对象的监视器上 或者我们可以用方法中的私有最终对象锁替换类的 this 上标记
  • 使用 Bash 按进程名称检查 Mac 进程是否正在运行

    如何使用 Bash 脚本中的进程名称检查 Mac OS X 上的进程是否正在运行 我正在尝试编写一个 Bash 脚本 如果进程已停止 它将重新启动进程 但如果进程仍在运行 则不执行任何操作 解析这个 ps aux grep v grep g

随机推荐

  • WebGL 如何避免长时间着色器编译导致选项卡停顿

    我有一个巨大的着色器 需要一分多钟的时间来编译 在这个过程中完全停止了整个浏览器 据我所知 着色器编译不能异步 因此您可以在等待编译完成时运行其他 WebGL 命令 我已经尝试过以下操作 在一段时间内不要使用该特定着色器 这不起作用 因为大
  • 如何以编程方式将 css 类应用到 asp.net 控件?

    我想知道如何通过 C 后端将 CSS 类应用到 ASP NET 控件 本例中为 TextBox 例如
  • 如何将 int[] 连接到 .NET 中的字符分隔字符串?

    我有一个整数数组 int number new int 2 3 6 7 将它们转换为单个字符串的最简单方法是什么 其中数字由字符分隔 例如 2 3 6 7 我正在使用 C 和 NET 3 5 var ints new int 1 2 3 4
  • Angular:$http 请求给出 -1 状态

    Node js 服务器给出 这是一个字符串 写头 写 字符串 结束 当执行 http 请求时 我看到 Node js 服务器正在响应并发回信息 在 Angular 中我执行以下请求 angular module phoneList comp
  • JavaScript 查询选择器全部

    我正在编写的教程包含以下代码和以下注释 我不明白 i 评论 特别是为什么它说 所有第二个表格单元格 第二 是什么意思 这不是正确的英语 ii 当它说的时候 它到底在寻找什么td td 该程序是关于从表中获取数据 所以td td选择 html
  • JPA 多重联接

    我有这些课程 class Project ManyToOne Company owner ManyToMany Set
  • 光滑的滑块转到第一张幻灯片

    Slick 滑块设置为自动播放 播放时 幻灯片从左到右或从第一个到最后一个 当滑块到达最后一张幻灯片时 它将开始从最后一张幻灯片向后自动播放到第一张幻灯片 我希望当滑块到达最后一张幻灯片时 滑块从第一张幻灯片开始播放 而不是从最后一张幻灯片
  • 如何使用 sqlcmd 运行 sql 脚本文件并输出到 shell 和文件

    我正在尝试使用以下命令从文件运行 sql 脚本sqlcmd 使用以下命令 sqlcmd S
  • Ruby 中 $stdout 和 STDOUT 之间的区别

    在 Ruby 中 有什么区别 stdout 前面有美元符号 和STDOUT 全部大写 在进行输出重定向时 应该使用哪个以及为什么 同样适用于 stderr and STDERR Edit 刚刚找到一个相关问题 https stackover
  • 该结构的初始序列是什么?

    我遇到了最初的序列概念 通过标准搜索initial sequence短语只给出 3 个结果 并且没有给出定义 Section N3797 9 5 1 class union 如果标准布局联合包含多个标准布局结构 有着共同点的初始序列 9 2
  • Python CGI os.system 导致标头格式错误

    我正在运行 Apache 2 4 10 Raspbian 并且我正在使用 python 作为 CGI 但是当我尝试在简单代码中使用 os system 时 我收到此格式错误的标头错误 Wed Aug 31 17 10 05 715740 2
  • Visual Studio 2012 Ultimate 编辑 C# 代码时速度缓慢

    我检查了许多有关禁用图形加速 关闭 IntelliTrace 和使用 Sysinternals Process Monitor ProcMon 的文章 但我不知道如何找出导致我的编辑器速度慢得离谱的原因 ProcMon 显示 devenv
  • 最优算法是完整算法吗?

    我确实理解 完整的算法是一种如果有解决方案 该算法能够找到它的算法 而最佳算法是一种能够找到成本最低的解决方案的算法 但最优算法就是完整算法吗 可以简单解释一下吗 Thanks 是的 根据定义 寻找最优解需要证明最优性 这可以通过找到所有解
  • 插入符号位置不跟踪?

    我想做的是将关键代码放入一个数组中 以便稍后做一些有趣的事情 因此 我捕获击键 获取插入符位置并将关键代码放入数组中 在 MooTools 的帮助下 var keyArray form addEvent keyup function eve
  • 从html表单的下拉框中获取选定的值而不提交

    如何从html表单的下拉框元素中获取所选项目的文本 使用Python 当我使用鼠标从下拉框中选择一项时 如何将值存储到变量中 即不使用提交按钮 这是针对我在仅支持 Python 的应用程序引擎中执行的应用程序 你的问题表明对如何进行一些误解
  • 为什么某些 xlims 和 ylims 在 ggplot 和 sf 中产生此错误?

    我正在学习使用 ggplot 和 sf 来处理空间数据 当我尝试绘制以下图时 出现错误 library sf library ggplot2 library rnaturalearth library rnaturalearthdata w
  • 如何将文件路径数组转换为分层 JSON 结构

    我正在尝试根据给定的所有文件和路径的数组创建机器目录结构的 JSON 该数组看起来像这样 string dirArray proc 15 task 15 exe proc 15 task 15 mounts mounts xml proc
  • Qt 的 Bullseye 代码覆盖率

    嘿 我面临着有关 Qt 的靶心代码覆盖率的问题 在我的 pro 文件中 我添加以下内容 QMAKE CC C Program Files x86 BullseyeCoverage bin cl QMAKE CXX QMAKE CC QMAK
  • Chrome 扩展:如何在同一选项卡中打开 popup.html 中的网址

    谷歌浏览器扩展程序 我为一件简单的事情而发疯 请不要责怪我 我不是英语出身 我很难阅读和理解所有扩展文档 我只想执行以下操作 我的 popop html 中有 8 个不同的 URL 当我点击右上角浏览器栏中的图标时 它会打开 网址 exam
  • Go 是否可以在不为每个外部进程启动一个操作系统线程的情况下生成并与外部进程通信?

    简洁版本 Golang 是否可以生成多个外部进程 shell 命令 在平行下 这样它就不会启动一个操作系统线程每个外部进程 并且在完成后仍然能够接收其输出 更长的版本 在 Elixir 中 如果使用端口 则可以生成数千个外部进程 而无需真正