2016-07-18 16 views
1

プロセスが存在し、どのLinuxでも実行されているかどうかを確認する最も普遍的な方法を見つけたいと思います。マックOS Xがある場合、私はkqueue感謝を経由して、これを行うために利用可能な思いのUnix/BSDでは/proc/[pid]/statは、すべてのlinuxディストリビューションで常に利用できますか?

EVFILT_PROC/NOTE_EXITを使用してsyscall.Kqueue()にそれは問題では、NetBSDの、FreeBSDでは、などのコードはうまく動作し、監視するのに役立ちますしません。 PIDの状態。 Linux上で同じことを達成しようとし

は、私がここで提案のようにkill -s 0、代わりに信号0を送信する、/proc/[pid]/statファイルの存在を定期的にチェックするためにアイデアを来た:https://stackoverflow.com/a/15210305/1135424主に非そのためのロジックを簡素化します既存のプロセスに対して-nilエラーが返される可能性があります。

おそらくのようなもの使用:

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にフォールバックすることができますが、主に多くのCPUリソースを消費しないために、ループでスリープ状態にならないようにするために、使用可能な可能性のあるソリューション(おそらくinotify)

答えて

0

子プロセスの場合は、waitpidを使用してください。

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 
     } 
    } 
} 

あなたのケースのために使用可能であるかもしれないプロセスイベントのためのネットリンクAPI(http://netsplit.com/the-proc-connector-and-socket-filters)があります

関連する問題