package main

import (
"log"
"os"
"bufio"
"github.com/docker/docker/pkg/reexec"
   "os/exec"
   "sync"
)

func init() {
   log.Printf("init start, os.Args = %+v\n", os.Args)
   reexec.Register("childProcess", childProcess)
   if reexec.Init() {
      reader := bufio.NewReader(os.Stdin)
      reader.ReadString('\n')
      os.Exit(0)
   }
}

func childProcess() {
   log.Println("childProcess")
}

func main() {
   log.Printf("main start, os.Args = %+v\n", os.Args)
    cmd :=make([]*exec.Cmd,5)

   var wg sync.WaitGroup
   wg.Add(5)
   for i:=0;i<5;i++{
       go func(i int,cmd []*exec.Cmd){
          cmd[i] = reexec.Command("childProcess")
          cmd[i] .Stdin = os.Stdin
          cmd[i] .Stdout = os.Stdout
          cmd[i] .Stderr = os.Stderr
          if err := cmd[i] .Start(); err != nil {
             log.Panicf("failed to run command: %s", err)
          }
          log.Println("started,begin to wait...",i)
          wg.Done()
       }(i,cmd)
    }

   wg.Wait()

    for j:=0;j<5;j++{
       if err := cmd[j] .Wait(); err != nil {
          log.Panicf("failed to wait command[%d]: %s", j,err)
       }
    }

   log.Println("main exit")
   reader := bufio.NewReader(os.Stdin)
   reader.ReadString('\n')
}

 或者:

 

package main

import (
    "bufio"
    "fmt"
    "github.com/vishvananda/netns"
    "log"
    "net"
    "os"
    "os/exec"
    "runtime"
    "strconv"
    "sync"

    "reflect"
    "unsafe"
)

func init() {
    if len(os.Args) > 1 {
        SetProcessName(os.Args[1]+" process")
    }
}

func SetProcessName(name string) error {
    argv0str := (*reflect.StringHeader)(unsafe.Pointer(&os.Args[0]))
    //log.Println("old process name:",argv0str)
    argv0 := (*[1 << 30]byte)(unsafe.Pointer(argv0str.Data))[:argv0str.Len]

    n := copy(argv0, name)
    if n < len(argv0) {
        for k:=n;k<len(argv0);k++{
            argv0[k] = 0
        }
    }
    return nil

}

func main() {
    log.Printf("main start, os.Args = %+v , processID:%d \n", os.Args, os.Getpid())

    param := "run"
    if len(os.Args) > 1 {
        param = os.Args[1]
    }

    switch param {
    case "run":
        parent()
    case "child":
        child()
    default:
        panic("wat should I do")
    }

    reader := bufio.NewReader(os.Stdin)
    reader.ReadString('\n')
    //for;;{
    //    time.Sleep(time.Millisecond*1000)
    //}

}

func parent() {
    childNum := 2
    cmd := make([]*exec.Cmd, childNum)
    var wg sync.WaitGroup

    wg.Add(childNum)
    for i := 0; i < childNum; i++ {
        go func(i int, cmd []*exec.Cmd) {
            cmd[i] = exec.Command("/proc/self/exe", append(append([]string{"child"}), strconv.Itoa(i))...)
            cmd[i].Stdin = os.Stdin
            cmd[i].Stdout = os.Stdout
            cmd[i].Stderr = os.Stderr
            if err := cmd[i].Run(); err != nil {
                fmt.Println("ERROR", err)
                os.Exit(1)
            }
        }(i, cmd)
        wg.Done()
    }
    wg.Wait()
    log.Println("Parent process running,pid:", os.Getpid())

}

func child() {
    //cmd := exec.Command("/proc/self/exe",os.Args...)
    //cmd.Stdin = os.Stdin
    //cmd.Stdout = os.Stdout
    //cmd.Stderr = os.Stderr
    //
    //if err := cmd.Run(); err != nil {
    //    fmt.Println("ERROR", err)
    //    os.Exit(1)
    //}
    runtime.LockOSThread()
    defer runtime.UnlockOSThread()

    go func() {
        log.Println("childProcess begin...", os.Args[1])
        origns, _ := netns.Get()
        defer origns.Close()
        log.Println("origin namespace:", origns.String())

        newNS, err := netns.GetFromName("net" + os.Args[2])
        if err != nil {
            log.Println("get ns err:", err.Error())
        }
        log.Println("pid:", os.Getpid(), " new namespace :", newNS.UniqueId())
        netns.Set(newNS)
        defer newNS.Close()
        ifaces, _ := net.Interfaces()
        log.Println(fmt.Sprintf("Interfaces: %v\n", ifaces))

        nowNS, err := netns.Get()
        if err != nil {
            log.Println("get ns failed:", err.Error())
        }
        log.Println("final orig namespace :", nowNS.UniqueId())
    }()
    log.Println("Child process running,pid:", os.Getpid())
}

func must(err error) {
    if err != nil {
        panic(err)
    }
}
 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐