Tôi đang sử dụng GO để kiểm tra xem liệu một quy trình (không phải là cha mẹ) có bị chấm dứt hay không, về cơ bản giống như lệnh pwait trong FreeBSD nhưng được viết bằng văn bản.Làm cách nào để chờ một sự kiện/quá trình hoàn thành không phải là phụ huynh?
Hiện nay tôi đang cố gắng một for loop
với một kill -0
, nhưng tôi nhận thấy rằng việc sử dụng CPU là rất cao 99% với cách tiếp cận này, đây là mã:
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)
}
Bất kỳ ý tưởng về làm thế nào để cải thiện hoặc thực hiện đúng cách này.
Xin cảm ơn trước.
CẬP NHẬT
Thêm một sleep
trong vòng lặp như gợi ý, giúp giảm tải.
Từ các liên kết được cung cấp, dường như có thể đính kèm với pid hiện tại, tôi sẽ thử PtraceAttach nhưng không biết liệu điều này có thể có phản ứng phụ hay không?
Như đề nghị tôi đã có sẵn để sử dụng 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")
}
Hoạt động tốt, nhưng tự hỏi làm thế nào để thực hiện/đạt được như nhau trên linux kể từ khi tôi nghĩ kqueue
không có sẵn trên nó, bất kỳ ý tưởng?
Một số ý tưởng từ câu hỏi này: [Cách đợi để thoát khỏi các quy trình không phải trẻ em] (http://stackoverflow.com/q/1157700) –
Đặt một giấc ngủ ngắn trong vòng lặp của bạn. Linux không cung cấp cách hiệu quả để thực hiện điều này – JimB
API 'kqueue' có thể sử dụng được từ' go' (trong gói 'syscall') và nếu không cần tính di động, ngoài * BSD và Darwin, thì BSD' pwait 'tiện ích có thể được dịch sang' go'. – kdhp