Używam GO, aby sprawdzić, czy proces (nie był nadrzędny) ma ben zakończona, w zasadzie coś jak komenda pwait w FreeBSD, ale napisane w programie go.Jak właściwie czekać na zakończenie wydarzenia/procesu, który nie jest rodzicem?
Obecnie staram się for loop
z kill -0
, ale widzę, że użycie procesora jest bardzo wysoka 99% z tym podejściem, oto kod:
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)
}
Każdy pomysł, jak poprawić lub właściwie to zaimplementuj.
Z góry dziękuję.
UPDATE
Dodawanie sleep
wewnątrz pętli jak zasugerował, pomaga w zmniejszeniu obciążenia.
Z podanych linków, wydaje się być możliwe dołączenie do istniejącego pid, spróbuję PtraceAttach, ale nie wiem, czy to może mieć efekty uboczne, jakiś pomysł?
Jak sugeruje byłam dostępna do wykorzystania 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")
}
działa prawidłowo, ale zastanawiasz się, jak wdrożyć/osiągnąć to samo na linux ponieważ myślę kqueue
niedostępne w nim, jakieś pomysły?
Kilka pomysłów na to pytanie: [Jak czekać na wyjście z procesów innych niż dzieci] (http://stackoverflow.com/q/1157700) –
Umieść krótki sen w pętli for. Linux nie zapewnia wydajnego sposobu na wykonanie tego kodu. – JimB
Interfejs API 'kqueue' może być użyty z' go' (w pakiecie 'syscall'), a jeśli przenośność nie jest wymagana, poza * BSD i Darwin, a następnie BSD' pwait 'narzędzie może być przetłumaczone na' go'. – kdhp