所有Linux发行版中的/ proc / [pid] / stat是否始终可用?

时间:2016-07-18 22:14:41

标签: linux go pid

我想找到最好的通用方法来检查进程是否存在并且是否在任何linux上运行。

在Unix / BSD中我可以通过kqueue执行此操作,这要归功于syscall.Kqueue()使用EVFILT_PROC / NOTE_EXIT它没有'重要的是,如果是mac os X,netbsd,freebsd等,代码将正常工作,并有助于监控PID的状态。

试图在linux上实现相同的目标,我想到了定期检查/proc/[pid]/stat文件是否存在的想法,而不是像这里建议的那样发送信号0,kill -s 0:{{3主要是为了简化逻辑,因为可以为现有进程返回非零错误。

可能使用类似的东西:

initialStat, err := os.Stat(fmt.Sprintf("/proc/%d/stat", self.pid)                                                                                                                                                           
if err != nil {                                                                                                                                                                                                              
    return                                                                                                                                                                                                                   
}                                                                                                                                                                                                                            

for {                                                                                                                                                                                                                        
    stat, err := os.Stat(fmt.Sprintf("/proc/%d/stat", self.pid)                                                                                                                                                              
    if err != nil {                                                                                                                                                                                                          
        return err                                                                                                                                                                                                           
    }                                                                                                                                                                                                                        

    if stat.Size() != initialStat.Size() || stat.ModTime() != initialStat.ModTime() {                                                                                                                                        
        return nil                                                                                                                                                                                                           
    }       
    // wondering how to avoid sleeping here
    time.Sleep(time.Second)                                                                                                                                                                                                                 
}

但是想知道在所有linux /proc/[pid]/stat中是否总是可用或者通过发送信号0 kill -0 $PID基本上做同样的事情。

最后,我总是可以回退到kill -O $PID,但只是想知道可以使用哪些可行的解决方案(可能是inotify),目的是避免在循环中睡眠,主要是为了不消耗大量的CPU资源。 / p>

1 个答案:

答案 0 :(得分:0)

对于子进程,您应该使用waitpid

可以使用适用于您的案例的流程事件(http://netsplit.com/the-proc-connector-and-socket-filters)的netlink API:

http://godoc.org/github.com/cloudfoundry/gosigar/psnotify#PROC_EVENT_EXIT

import "github.com/cloudfoundry/gosigar/psnotify"

func waitpid(pid int) error {
    watcher, err := psnotify.NewWatcher()
    if err != nil {
        return err
    }

    if err := watcher.Watch(pid, psnotify.PROC_EVENT_EXIT); err != nil {
        return err
    }

    defer watcher.Close()

    // At this point, you should probably syscall.Kill(pid, 0) to check that the process is still running.

    for {
        select {
        case ev := <-watcher.Error:
            // TODO..
            return ev
        case <-watcher.Exit:
            return nil
        }
    }
}