Ich verwende GO, um zu überprüfen, ob ein Prozess (nicht übergeordnet) beendet wurde, im Grunde so etwas wie der pwait Befehl in FreeBSD aber geschrieben in gehen.Wie man richtig auf ein Ereignis/einen Prozess wartet, um zu beenden, nicht das Elternteil zu sein?
Derzeit versuche ich ein for loop
mit einem kill -0
, aber ich merke, dass die CPU-Auslastung ist sehr hoch 99% mit diesem Ansatz, hier ist der Code:
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)
}
Jede Idee, wie man verbessern oder richtig umsetzen.
Vielen Dank im Voraus.
UPDATE
eine sleep
innerhalb der Schleife Hinzufügen wie vorgeschlagen, hilft, die Belastung zu reduzieren.
Von den bereitgestellten Links scheint es möglich, an die vorhandene PID anzuhängen, werde ich versuchen PtraceAttach aber weiß nicht, ob dies Nebenwirkungen haben kann, keine Ahnung?
Wie vorgeschlagen, dass ich zur Verfügung stand verwenden kqueue: fein
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")
}
funktioniert, aber frage mich, wie das gleiche auf Linux zu implementieren/zu erreichen, da ich kqueue
nicht auf sie denken, irgendwelche Ideen?
Einige Ideen aus dieser Frage: [Wie warten auf den Ausgang von Nicht-Kinder-Prozesse] (http://stackoverflow.com/q/1157700) –
Legen Sie einen kurzen Schlaf in Ihre for-Schleife. Linux bietet keinen effizienten Weg, dies zu tun – JimB
Die 'kqueue' API ist von' go' (im 'syscall' Paket) verwendbar, und wenn Portabilität nicht erforderlich ist, über * BSD und Darwin hinaus, dann ist der BSD' pwait 'Utility könnte in' go' übersetzt werden. – kdhp