douyue5856 2017-02-28 09:47
浏览 37
已采纳

操作系统:发送syscall.SIGCONT时进程已经完成(可能的错误?)

When executing a process and sending signals to it using: Process.Signal I notice that after sending the second signal syscall.SIGCONT I got a: os: process already finished but if using syscall.Kill everything works as expected.

For demonstrative purposes I have created this naive example:

package main

import (
    "fmt"
    "os"
    "os/exec"
    "syscall"
    "time"
)

func main() {
    exit := make(chan error, 1)
    go run(exit)

    for {
        select {
        case <-exit:
            println("fin, restarting")
            run(exit)
        default:
            time.Sleep(time.Second)
            println("running...")
        }
    }
}

func run(ch chan<- error) {
    cmd := exec.Command("sleep", "3")
    if err := cmd.Start(); err != nil {
        print(err.Error())
        os.Exit(1)
    }
    fmt.Printf("Pid: %d
", cmd.Process.Pid)
    go func() {
        ch <- cmd.Wait()
    }()

    time.Sleep(2 * time.Second)
    fmt.Printf("%v
", cmd.Process.Signal(syscall.SIGSTOP))

    time.Sleep(2 * time.Second)

    // Using this will return an os: process already finished  
    fmt.Printf("%v
", cmd.Process.Signal(syscall.SIGCONT)) 

    // This works as expected
    //fmt.Printf("%v
", syscall.Kill(cmd.Process.Pid, syscall.SIGCONT))
}

So basically if using:

cmd.Process.Signal(syscall.SIGCONT)

os: process already finished is returned

But when using:

syscall.Kill(cmd.Process.Pid, syscall.SIGCONT)

It works as expected.

Could this be a bug on os.exec or it the expected behavior?

UPDATE: seems to be happening only on mac os X

  • 写回答

1条回答 默认 最新

  • douyun3887 2017-03-01 08:37
    关注

    This issue seems to be only happening on Mac OS X, tested on "Sierra" and "El Capitan" https://go-review.googlesource.com/#/c/37610/

    So, for now, to keep things cross-platform better user:

    syscall.Kill(cmd.Process.Pid, syscall.SIGCONT))
    

    Example code to test if your system has this issue:

    package main
    
    import (
        "fmt"
        "log"
        "os/exec"
        "syscall"
        "unsafe"
    )
    
    func main() {
        cmd := exec.Command("sleep", "10")
        if err := cmd.Start(); err != nil {
            log.Fatal(err)
        }
    
        // signal when wait4 will return immediately
        go func() {
            var siginfo [128]byte
            psig := &siginfo[0]
            _, _, e := syscall.Syscall6(syscall.SYS_WAITID, 1, uintptr(cmd.Process.Pid), uintptr(unsafe.Pointer(psig)), syscall.WEXITED|syscall.WNOWAIT, 0, 0)
            fmt.Println("WAITID RETURNED -- this shouldn't happen:", e)
        }()
    
        err := cmd.Process.Signal(syscall.SIGSTOP)
        if err != nil {
            log.Fatal(err)
        }
        cmd.Wait()
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥60 pb数据库修改或者求完整pb库存系统,需为pb自带数据库
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路