私はのpwaitコマンドのようなものですが、プロセス(親ではない)が終了していないかどうかを確認するのに、GOを使用しています。イベント/プロセスが親でなくなるのを正しく待つ方法は?
現在、私はkill -0
でfor loop
をしようとしていますが、私は、CPUの使用率がこのアプローチの99%非常に高いことがわかり、ここでのコードは次のとおりです。
package main
import (
"fmt"
"os"
"strconv"
"syscall"
"time"
)
func main() {
if len(os.Args) != 2 {
fmt.Printf("usage: %s pid", os.Args[0])
os.Exit(1)
}
pid, err := strconv.ParseInt(os.Args[1], 10, 64)
if err != nil {
panic(err)
}
process, err := os.FindProcess(int(pid))
err = process.Signal(syscall.Signal(0))
for err == nil {
err = process.Signal(syscall.Signal(0))
time.Sleep(500 * time.Millisecond)
}
fmt.Println(err)
}
改善する方法の任意のアイデアこれを適切に実装してください。
ありがとうございます。提案のよう
UPDATE
ループ内sleep
の追加負荷を低減することに役立ちます。
提供されているリンクから、既存のPIDにアタッチすることができるようですが、私は試してみますPtraceAttachこれは副作用、任意のアイデアがあるかどうかわからないのですか?
としては、私はkqueueを使用するために利用できることを示唆した。
package main
import (
"fmt"
"log"
"os"
"strconv"
"syscall"
)
func main() {
if len(os.Args) != 2 {
fmt.Printf("usage: %s pid", os.Args[0])
os.Exit(1)
}
pid, err := strconv.ParseInt(os.Args[1], 10, 64)
if err != nil {
panic(err)
}
process, _ := os.FindProcess(int(pid))
kq, err := syscall.Kqueue()
if err != nil {
fmt.Println(err)
}
ev1 := syscall.Kevent_t{
Ident: uint64(process.Pid),
Filter: syscall.EVFILT_PROC,
Flags: syscall.EV_ADD,
Fflags: syscall.NOTE_EXIT,
Data: 0,
Udata: nil,
}
for {
events := make([]syscall.Kevent_t, 1)
n, err := syscall.Kevent(kq, []syscall.Kevent_t{ev1}, events, nil)
if err != nil {
log.Println("Error creating kevent")
}
if n > 0 {
break
}
}
fmt.Println("fin")
}
細かい機能しますが、任意のアイデア、私はそれでkqueue
利用できないと思いますので、Linux上で同じことを達成/実装する方法を疑問に思いますか?
この質問のいくつかのアイデア:[子供以外のプロセスの終了を待つ方法](http://stackoverflow.com/q/1157700) –
forループに短いスリープを入れてください。 Linuxはこれを行うための効率的な方法を提供していません – JimB
'kqueue' APIは(' 'syscall'パッケージで)' go'から使用できます。移植性が必要ない場合、* BSDとDarwinを超えていれば、BSD 'pwait 'ユーティリティは' go'に変換される可能性があります。 – kdhp