社区首页 >问答首页 >每个外部进程可以在不启动一个OS线程的情况下与外部进程进行派生和通信吗?

每个外部进程可以在不启动一个OS线程的情况下与外部进程进行派生和通信吗?
EN

Stack Overflow用户
提问于 2015-11-26 16:19:50
回答 1查看 3.7K关注 0票数 11

简写版:

在Golang中是否可以在并行的中生成许多外部进程(shell命令),这样它就不会在每个外部进程中启动一个操作系统线程.当它完成时还能接收到它的输出吗?

更长版本:

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

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

代码语言:javascript
代码运行次数:0
复制
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,或者类似的,如果我正确理解的话):

代码语言:javascript
代码运行次数:0
复制
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天)的进程,在操作系统中任何虚拟或物理限制都会造成尽可能少的问题。

(对代码中的任何错误表示抱歉,因为我对“灵丹妙药”还不熟悉,而且还很新。我渴望了解我正在做的任何错误。)

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

EN

回答 1

Stack Overflow用户

发布于 2015-11-26 22:27:51

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

但是,如果不通过golang包使用操作系统线程,就不可能读取进程的stdout。我认为这是因为os包没有使用非阻塞io来读取管道。

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

代码语言:javascript
代码运行次数:0
复制
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
            }
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33948726

复制
相关文章
VC++中如何启动外部进程和关闭某个进程
三个SDK函数: WinExec, ShellExecute,CreateProcess
ccf19881030
2020/05/27
2.9K0
Electron渲染进程与主进程进行通信
remote在旧版本是内置的模块, 但是在新版本将被弃用,要用@electron/remote进行代替
明知山
2021/12/13
7310
进程和线程的概念、区别及进程线程间通信
进程是对运行时程序的封装,是系统进行资源调度和分配的的基本单位,实现了操作系统的并发;
海盗船长
2020/08/27
37.4K0
进程间通信和线程间通信的区别_有些线程包含多个进程
进程间通信 转自 https://www.cnblogs.com/LUO77/p/5816326.html
全栈程序员站长
2022/11/08
1.2K0
进程间通信和线程间通信的区别_有些线程包含多个进程
进程访问外部接口的超时设置
    早上发现WEB SRV上的FCGI进程全部挂住了,查看日志才发现是访问一个外部接口的时候因为失败率比较高,导致FCGI进程都堵在接收回包上了,因为超时设了500ms,结果每个进程每秒只能处理2个请求,大量用户请求失败,所以用户不停地重试产生了滚雪球效应,后来调高进程数临时解决,后面继续梳理超时时间。
王亚昌
2018/08/03
1K0
从并发处理谈PHP进程间通信(一)外部介质
枕边书
2018/01/04
1.2K0
进程/线程间通信
因为线程是共享内存空间的,所以线程间通信相比于进程间通信会简单一些,线程间通信的体现
Helloted
2022/06/07
7080
进程/线程间通信
进程的同步、互斥、通信的区别,进程与线程同步的区别
这两天看进程的同步与通信,看了几本书上的介绍,也从网上搜了很多资料,越看越迷惑,被这几个问题搞得很纠结。
全栈程序员站长
2022/11/15
1.2K0
获取外部进程窗口中listview中的列名
aardio中提供了操作外部进程listview控件的库函数:winex.ctrl.listview,但是该函数库没有提供直接获取列名的函数。而aardio的进程内listview库可以直接获取列名,相关的函数名是:getColumnText()。查看win.ui.ctrl.listview的代码后发现:getColumnText()函数是调用getColumn()函数获取列名信息的,而外部进程的listview库里面有getColumn()这个函数,所以使用起来也不麻烦。
用户2135432
2023/10/21
2140
获取外部进程窗口中listview中的列名
你知道何为线程与进程吗??
什么是线程?线程与进程与有什么关系?这是一个非常抽象的问题,也是一个特别广的话题,涉及到非常多的知识。我不能确保能把它讲的话,也不能确保讲的内容全部都正确。即使这样,我也希望尽可能地把他讲通俗一点,讲的明白一点,因为这是个一直困扰我很久的,扑朔迷离的知识领域,希望通过我的理解揭开它一层一层神秘的面纱。
刘盼
2018/07/26
8840
你知道何为线程与进程吗??
你知道何为线程与进程吗??
什么是线程?线程与进程与有什么关系?这是一个非常抽象的问题,也是一个特别广的话题,涉及到非常多的知识。我不能确保能把它讲的话,也不能确保讲的内容全部都正确。即使这样,我也希望尽可能地把他讲通俗一点,讲的明白一点,因为这是个一直困扰我很久的,扑朔迷离的知识领域,希望通过我的理解揭开它一层一层神秘的面纱。
Java高级架构
2018/10/22
5060
你知道何为线程与进程吗??
如何在父进程中读取子(外部)进程的标准输出和标准错误输出结果
        最近接手一个小项目,要求使用谷歌的aapt.exe获取apk软件包中的信息。依稀记得去年年中时,有个同事也问过我如何获取被调用进程的输出结果,当时还研究了一番,只是没有做整理。今天花点时间,将该方法整理成文。(转载请指明出于breaksoftware的csdn博客)
方亮
2019/01/16
3.9K0
进程与线程
  进程是表示资源分配的基本单位,又是调度运行的基本单位。例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格、内存空间、磁盘空间、I/O设备等。然后,把该进程放人进程的就绪队列。进程调度程序选中它,为它分配CPU以及其它有关资源,该进程才真正运行。所以,进程是系统中的并发执行的单位。
王大力测试进阶之路
2020/01/23
1.3K0
进程与线程
一般来讲,当启动一个应用程序时,系统里就生成了一个进程, 这个进程拥有自己的内存空间。(我们平时用windows的任务管理器看到的也就是进程) 但也有特殊:比如IE8,它采用了多进程设计,打开IE8后,会在任务管理器里有多个iexplore.exe 每个进程内部可以创建多个线程, 这些线程之间共用一个进程的内存空间(即线程之间可共享内存)。 我们做多线程开发,其实就是在同一个进程内部创建了多个线程。
菩提树下的杨过
2018/01/23
6270
进程与线程
  我们都知道计算机的核心是CPU,它承担了所有的计算任务,而操作系统是计算机的管理者,它负责任务的调度,资源的分配和管理,
全栈程序员站长
2022/09/07
3030
进程与线程
进程与线程
除此之外,我们在JDK8之后,我们可以采用函数式接口Lambda来简化Runnable的书写:
秋落雨微凉
2022/11/18
7390
进程与线程
进程与线程
进程是计算机中一个独立的执行单位,它是操作系统分配资源和调度的基本单位,每个进程都有自己的内存空间,互相之间不会影响
才疏学浅的木子
2023/10/17
1840
进程与线程
进程与线程的联系和区别?
1、线程的基本概念 概念: 线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。 好处 : (1)易于调度。 (2)提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。 (3)开销少。创建线程比创建进程要快,所需开销很少。。 (4)利于充分发
麦克劳林
2018/09/11
16.9K0
linux多进程与进程间通信_linux共享内存进程间通信
Linux下进程间通信-共享内存 – 码到城攻共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式
全栈程序员站长
2022/11/07
4.5K0
linux多进程与进程间通信_linux共享内存进程间通信
Python进程间通信和进程池
可以使用multiprocessing模块的Queue实现多个进程之间的数据传递。Queue本身是一个消息列队程序。
Python碎片公众号
2021/02/26
8390
Python进程间通信和进程池

相似问题

Lisp与外部进程通信

10

Rust中与外部进程的多线程通信

10

可以从它外部派生一个进程吗?

51

Elixir/Erlang:与外部进程通信

20

守护进程可以用STDOUT启动外部进程吗?

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文