os.Wait on more than 1 process

712 views
Skip to first unread message

creack

unread,
Dec 28, 2010, 8:03:16 AM12/28/10
to golang-nuts
Hello,

I am using ForkExec in loop and I would like to wait for all them
after the loop. In C, this would be with WAIT_ANY, but I didn't
managed to get it in Go.

I tried os.Wait() with -1/0 as pid but it didn't really understand
what was the result, I had a lot of notifications but none for my
childs processes.
I tried with cgo to call waitpid() but it does not see child process.

I could use os.Wait() with a specific pid and launch it in goroutines,
but it seems very complicated for what it is.

Someone have an idea?

Marcin 'Qrczak' Kowalczyk

unread,
Dec 28, 2010, 8:07:19 AM12/28/10
to creack, golang-nuts
2010/12/28 creack <charmes....@gmail.com>:

> I could use os.Wait() with a specific pid and launch it in goroutines,
> but it seems very complicated for what it is.

I don't understand the problem. Just wait for all pids you launched
sequentially.

--
Marcin Kowalczyk

Gustavo Niemeyer

unread,
Dec 28, 2010, 8:10:43 AM12/28/10
to creack, golang-nuts
Hey there,

> I tried os.Wait() with -1/0 as pid but it didn't really understand
> what was the result, I had a lot of notifications but none for my
> childs processes.

I don't know what you're doing there, but this works fine here:

package main
import "os"

func sleep() {
os.ForkExec("/bin/sh", []string{"/bin/sh", "-c", "sleep 3"},
[]string{}, "", nil)
}

func main() {
sleep()
sleep()
for i := 0; i != 2; i++ {
msg, _ := os.Wait(-1, 0)
println(msg.Pid, " exited")
}
}

--
Gustavo Niemeyer
http://niemeyer.net
http://niemeyer.net/blog
http://niemeyer.net/twitter

creack

unread,
Dec 28, 2010, 8:25:08 AM12/28/10
to golang-nuts
@Gustavo: I am sorry, I forget to say that I need to use WUNTRACED.
And with this option, this code does not work.
@Marcin: I can't wait sequentially, I need to launch all processes and
then to wait for them. Any of them could end first and I need to
report it.

Gustavo Niemeyer

unread,
Dec 28, 2010, 8:51:31 AM12/28/10
to creack, golang-nuts
> @Gustavo: I am sorry, I forget to say that I need to use WUNTRACED.
> And with this option, this code does not work.

Using os.Wait(-1, os.WUNTRACED) in the provided snippet works fine for
me as well.

creack

unread,
Dec 28, 2010, 9:01:26 AM12/28/10
to golang-nuts
I am using darwin on amd64 with gc version 7012 and it is not working.


package main

import "os"

func sleep() {
os.ForkExec("/bin/sh", []string{"/bin/sh", "-c", "sleep 3"},
[]string{}, "", nil)
}

func main() {
sleep()
sleep()
for i := 0; i != 2; i++ {
msg, _ := os.Wait(-1,
os.WUNTRACED)
println(msg.Pid, " exited")
}
}

$>6g test.go && 6l test.6 && ./6.out
0 exited
0 exited

Gustavo Niemeyer

unread,
Dec 28, 2010, 9:14:00 AM12/28/10
to creack, golang-nuts
> I am using darwin on amd64 with gc version 7012 and it is not working.

With Ubuntu 10.10 on amd64 it works fine:

22442 exited
22444 exited

Would be worth debugging further to see where the issue is.

Benny Siegert

unread,
Dec 28, 2010, 11:28:22 AM12/28/10
to creack, golang-nuts
Hi!

On Tue, 28 Dec 2010, creack wrote:

> I am using ForkExec in loop and I would like to wait for all them
> after the loop. In C, this would be with WAIT_ANY, but I didn't
> managed to get it in Go.

I was told that using wait with PID 0 or -1 is dangerous in Go, due to
the way the runtime works. Using one goroutine per fork is the easiest
way:

import (
"fmt"
"os"
)

func doSomething(arg string, status chan *os.Waitmsg) {
pid, err := os.ForkExec( ... )
if err != nil { ... }

w, err := os.Wait(pid, 0)
// ... check value of err
status <- w
}

func main() {
var num int

status := make(chan *os.Waitmsg)
for _, arg := range os.Args[1:] {
go doSomething(arg, status)
num++
}
for i := 0; i < num; i++ {
w := <-status
if w != nil && w.Exited() {
fmt.Printf("Child (pid %v) exited with status
%v\n", w.Pid, w.ExitStatus())
}
}
}


--Benny.

creack

unread,
Dec 29, 2010, 7:36:40 AM12/29/10
to golang-nuts
Actually, the issue comes from os.WUNTRACED, I posted the problem on
the issue tracker.

On linux, it works fine. Thank you.

David Roundy

unread,
Jan 1, 2011, 5:24:27 PM1/1/11
to creack, golang-nuts
It seems like this would be a good place to use goroutines (and
possibly a chan), provided there aren't incredibly many incredibly
tiny processes being spawned.

David

--
David Roundy

Reply all
Reply to author
Forward
0 new messages