FAQ
Dear gophers,

I use the risky fork(2) in my code. In the child, I found syscall.Getpid()
and C.getpid() return different result. It's demonstrated in the following
code.
On fedora 17, x86_64, it will return something like,
child process (syscall): pid 28354, ppid 28352
child process (C): pid 28352, ppid 28352
Child exits 0

I'm not sure if it can be taken as a bug?

(The background problem: my requirement is an RPC server to serve some
requests(run some code) on behalf different user. I would like to
circumvent the fork(2) usage but found no elegant way by myself. Do I have
to invoke another program, such as su, to accomplish the work in such a
scenario? (I want to avoid it because I have to add command line interface
for each piece of code.))


-- demo code --

package main

// #include <unistd.h>
import "C"

import (
   "fmt"
   "log"
   "syscall"
)

func main() {
   r1, _, err := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
   //r1, _, err := syscall.Syscall(syscall.SYS_FORK, 0, 0, 0)
   if err != 0 {
     log.Fatal(err)
   }
   // r1 := C.fork()

   if r1 != 0 {
     var wstatus syscall.WaitStatus
     pid1, err := syscall.Wait4(int(r1), &wstatus, 0, nil)
     if err != nil || pid1 < 0 {
       log.Fatal(err)
     }
     exitStatus := wstatus.ExitStatus()
     fmt.Printf("Child exits %d\n", exitStatus)
     return
   }

   // child
   fmt.Printf("child process (syscall): pid %d, ppid %d\n",
     syscall.Getpid(), syscall.Getppid())
   fmt.Printf("child process (C): pid %d, ppid %d\n",
     C.getpid(), C.getppid())
}

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Dmitry Vyukov at Jun 17, 2013 at 3:19 pm

    On Mon, Jun 17, 2013 at 10:21 AM, wrote:
    Dear gophers,

    I use the risky fork(2) in my code. In the child, I found syscall.Getpid()
    and C.getpid() return different result. It's demonstrated in the following
    code.
    On fedora 17, x86_64, it will return something like,
    child process (syscall): pid 28354, ppid 28352
    child process (C): pid 28352, ppid 28352
    Child exits 0

    I'm not sure if it can be taken as a bug?

    (The background problem: my requirement is an RPC server to serve some
    requests(run some code) on behalf different user. I would like to
    circumvent the fork(2) usage but found no elegant way by myself. Do I have
    to invoke another program, such as su, to accomplish the work in such a
    scenario? (I want to avoid it because I have to add command line interface
    for each piece of code.))

    This is unsupported. Go programs can't fork.
    You need to start another program with os/exec.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Ian Lance Taylor at Jun 17, 2013 at 3:33 pm

    On Sun, Jun 16, 2013 at 11:21 PM, wrote:
    I use the risky fork(2) in my code. In the child, I found syscall.Getpid()
    and C.getpid() return different result. It's demonstrated in the following
    code.
    On fedora 17, x86_64, it will return something like,
    child process (syscall): pid 28354, ppid 28352
    child process (C): pid 28352, ppid 28352
    Child exits 0

    I'm not sure if it can be taken as a bug?
    You can not safely call fork in a Go program. Don't do it.

    Your odd results occur because the C.getpid call assumes that you
    called the C.fork call. C.getpid does not actually make a system call
    in the normal case. It reads the PID out of the thread descriptor.
    So mixing syscall.Fork and C.getpid is unpredictable. Anyhow, don't
    call fork.

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Minux at Jun 17, 2013 at 3:40 pm

    On Mon, Jun 17, 2013 at 2:21 PM, wrote:
    Dear gophers,

    I use the risky fork(2) in my code. In the child, I found syscall.Getpid()
    and C.getpid() return different result. It's demonstrated in the following
    code.
    On fedora 17, x86_64, it will return something like,
    child process (syscall): pid 28354, ppid 28352
    child process (C): pid 28352, ppid 28352
    Child exits 0

    I'm not sure if it can be taken as a bug?

    (The background problem: my requirement is an RPC server to serve some
    requests(run some code) on behalf different user. I would like to
    circumvent the fork(2) usage but found no elegant way by myself. Do I have
    to invoke another program, such as su, to accomplish the work in such a
    scenario? (I want to avoid it because I have to add command line interface
    for each piece of code.))
    it's because Go's getpid() will always use the real getpid syscall so
    it will always
    be correct.

    C's getpid() caches the old pid, and C's fork will update the cached copy.
    however, as fork in Go's syscall package directly invoke the fork syscall, the
    libc's cached copy is not updated.

    Using fork in a threaded program is asking for trouble, so please don't use
    fork in Go programs (even if you don't create any goroutines, the runtime
    might create several threads for its own use).

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • TL Qiu at Jun 18, 2013 at 2:45 am
    在 2013年6月17日星期一UTC+8下午11时40分11秒,minux写道:
    On Mon, Jun 17, 2013 at 2:21 PM, <kau...@gmail.com <javascript:>> wrote:
    Dear gophers,

    I use the risky fork(2) in my code. In the child, I found
    syscall.Getpid()
    and C.getpid() return different result. It's demonstrated in the following
    code.
    On fedora 17, x86_64, it will return something like,
    child process (syscall): pid 28354, ppid 28352
    child process (C): pid 28352, ppid 28352
    Child exits 0

    I'm not sure if it can be taken as a bug?

    (The background problem: my requirement is an RPC server to serve some
    requests(run some code) on behalf different user. I would like to
    circumvent the fork(2) usage but found no elegant way by myself. Do I have
    to invoke another program, such as su, to accomplish the work in such a
    scenario? (I want to avoid it because I have to add command line interface
    for each piece of code.))
    it's because Go's getpid() will always use the real getpid syscall so
    it will always
    be correct.

    C's getpid() caches the old pid, and C's fork will update the cached copy.
    however, as fork in Go's syscall package directly invoke the fork syscall,
    the
    libc's cached copy is not updated.

    Using fork in a threaded program is asking for trouble, so please don't
    use
    fork in Go programs (even if you don't create any goroutines, the runtime
    might create several threads for its own use).
    Thanks all kind replies to make it more clear.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJun 17, '13 at 3:14p
activeJun 18, '13 at 2:45a
posts5
users4
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase