2013-03-04 10 views
12

プロセスのPIDがある場合は、プロセスの既存のものをテストするにはos.FindProcessで十分ですか? errが返ってきたら、それが終了した(または殺された)と思いますか?プロセスが進行中であるかどうかをチェック

編集:

私はちょうどkill -s 0(古いスタイルのbashプロセス・テスト)の周りにラッパー関数を書いてきました。しますこれは何の問題もなく動作しますが、この問題に対する他のソリューション(GO図書館で行われる):

func checkPid(pid int) bool { 
    out, err := exec.Command("kill", "-s", "0", strconv.Itoa(pid)).CombinedOutput() 
    if err != nil { 
     log.Println(err) 
    } 

    if string(out) == "" { 
     return true // pid exist 
    } 
    return false 
} 

答えて

26

はプロセスが生きているかどうかを確認するために、従来のUNIXの方法ですシグナルは0です(あなたのbashの例のように)。

kill(2)から

If sig is 0, then no signal is sent, but error checking is still per‐ 
    formed; this can be used to check for the existence of a process ID or 
    process group ID. 

そして、あなたは123が死んで、そのプロセスを示す、これを取得、それを実行するとゴー

package main 

import (
    "fmt" 
    "log" 
    "os" 
    "strconv" 
    "syscall" 
) 

func main() { 
    for _, p := range os.Args[1:] { 
     pid, err := strconv.ParseInt(p, 10, 64) 
     if err != nil { 
      log.Fatal(err) 
     } 
     process, err := os.FindProcess(int(pid)) 
     if err != nil { 
      fmt.Printf("Failed to find process: %s\n", err) 
     } else { 
      err := process.Signal(syscall.Signal(0)) 
      fmt.Printf("process.Signal on pid %d returned: %v\n", pid, err) 
     } 

    } 
} 

に翻訳、プロセス1が生きているではなく、あなたが所有しており、プロセス12606は生きて所有しています。

$ ./kill 1 $$ 123 
process.Signal on pid 1 returned: operation not permitted 
process.Signal on pid 12606 returned: <nil> 
process.Signal on pid 123 returned: no such process 
+0

それはそれです! Goの方法を教えてくれてありがとう:) –

+0

なぜあなたは 'int64'に解析していますか? 'Atoi'は良くないでしょう(' FindProcess'では型変換されません)? – tjameson

+0

はい、あなたは正しいです。「アトー」が良いでしょう。私はもっ​​と最近、 'ParseInt'を使って忘れてしまったと思います! –

5

UNIX上(などのlinux、FreeBSDの、)システムなどが存在する場合、私はまだ満足しているos.FindProcessエラーを返すことはありません。私はWindows上で何が起こるか分からない。つまり、何かのために* os.Processを使用しようとするまで、PIDが正しいかどうかわかりません。

コードhereをご覧ください。

+0

あなたは正しいです。(上記の私の編集を参照してください) –

+0

Windowsの私の経験から、 'os.FindProcess'は与えられたPIDを持つプロセスが実行されていないとエラーを返します。 – Kerrmiter

1

システムに既知のPIDが見つからない場合(つまり、機能が不明)は、プロセスが確実に終了し、(UNIXの場合はwait call)結合されたことを意味します。

しかし、それ以外の方法は必ずしも真実ではありません。ちょうどpidが存在するため、以前と同じプロセスです。例えば、標準Linuxには65535個の有効なpidしかありません。ラップアラウンドがあるときに再利用することができます。しかし、実際には、実際にはこれを気にする必要はありません(間違った新しいプロセスが発見された場合、セキュリティ上の脆弱性や他の重大なものではなく、意図的に悪意のある目的)。

関連リンク(およびその右側の列に関連質問): - それお送りここ

+0

私は複数回upvoteできますことを願っています。最近のハードウェアでプロセスを確実に監視したいと思っている人にとって、pidが再利用されているという見解は重大です。何か不具合が生じて再生成された場合、pid名前空間はすぐに使い果たされます。スレッドIDはプロセスIDと同じ名前空間にあるため、スレッド化されたプロセスが問題を悪化させます。 – Mark

+1

言及を忘れた...確信が必要な場合は、$ pidの[プロセスの開始時刻](http://unix.stackexchange.com/a/7871/158521)がチェックの間に変更されていないことを確認してください。それがあれば、それは別のプロセスです。もしそうでなければ、それは非常に異なるプロセスであることはまずありません。 – Mark

+0

「非常にありそうもない」とはどういう意味ですか?どのような状況下では*別のプロセスではありませんか?プロセスが開始時間が何であっても1単位を超えていると仮定すると(PIDラップアラウンドを使って素早くダイ/再作成することでチェッカーを混乱させることはありませんでした)、私が考えることができる唯一の状況は開始時ラップアラウンドです。他にはありますか? –

2

また、syscall.Killを使用することもできます。それはコードの量が少なくなります。 Windowsでは

killErr := syscall.Kill(pid, syscall.Signal(0)) 
procExists := killErr == nil 
+0

[Nick Craig-Wood's answer](http://stackoverflow.com/a/15210305/55504)既存のプロセスに対して返すことができます。より複雑な条件付き(おそらく 'err == nil || err == syscall.EPERM'、多分もっと多くのもの)が必要です。 –

0

os.FindProcess()の結果を確認するプロセスが実行されているかどうかを確認するために十分であるように思われます。

func isProcessRunning(pid int) bool { 
    _, err = os.FindProcess(pid) 
    if err != nil { 
     return false 
    } 
    if runtime.GOOS == "windows" { 
     return true 
    } 
    return false // further checking for other systems then Windows is not supported here 
} 
関連する問題