Ce face os.FindProcess
os.FindProcess creează o valoare *os.Process pentru procesul cu numărul pid. Cu ea poți trimite semnale (p.Signal(os.Interrupt), p.Signal(syscall.SIGTERM)), poți opri procesul (p.Kill()) sau, dacă este procesul tău copil, îl poți aștepta (p.Wait()).
Pe Linux și macOS funcția reușește întotdeauna, chiar dacă procesul nu există; afli asta abia când trimiți un semnal. Un truc des folosit: p.Signal(syscall.Signal(0)) nu face nimic procesului, dar dă eroare dacă procesul nu există sau nu ai voie să-i trimiți semnale. Pe Windows, FindProcess dă eroare dacă procesul nu există.
Parametri
| Parametru | Descriere |
|---|---|
pid |
ID-ul procesului (de exemplu citit dintr-un fișier .pid). |
Ce returnează
Un *os.Process și nil (pe Unix mereu), sau o eroare.
Exemple
Exemplul 1: Semnal trimis propriului proces
package main
import (
"fmt"
"os"
"os/signal"
)
func main() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
p, err := os.FindProcess(os.Getpid())
fmt.Println("găsit:", p.Pid == os.Getpid(), err)
p.Signal(os.Interrupt)
fmt.Println("primit:", <-c)
}
Rezultat
găsit: true <nil>
primit: interrupt
Exemplul 2: Mai rulează procesul?
Pornim un proces copil, îl verificăm cu semnalul 0, îl oprim și verificăm din nou.
package main
import (
"fmt"
"os"
"os/exec"
"syscall"
)
func ruleaza(pid int) bool {
p, err := os.FindProcess(pid)
if err != nil {
return false
}
return p.Signal(syscall.Signal(0)) == nil
}
func main() {
cmd := exec.Command("sleep", "30")
cmd.Start()
pid := cmd.Process.Pid
fmt.Println("rulează:", ruleaza(pid))
p, _ := os.FindProcess(pid)
p.Kill()
cmd.Wait()
fmt.Println("după Kill rulează:", ruleaza(pid))
}
Rezultat
rulează: true
după Kill rulează: false
Exemplul 3: Oprirea unui server după fișierul .pid
package main
import (
"fmt"
"os"
"strconv"
"strings"
"syscall"
)
func main() {
date, err := os.ReadFile("/var/run/magazin.pid")
if err != nil {
fmt.Println("serverul nu pare pornit:", err)
return
}
pid, _ := strconv.Atoi(strings.TrimSpace(string(date)))
p, _ := os.FindProcess(pid)
if err := p.Signal(syscall.SIGTERM); err != nil {
fmt.Println("nu pot opri procesul", pid, ":", err)
return
}
fmt.Println("am cerut oprirea procesului", pid)
}
Rezultat posibil (diferă la fiecare rulare)
am cerut oprirea procesului 48213
Greșeli frecvente
- Verifici existența procesului doar prin eroarea lui
FindProcess. Pe Unix funcția reușește mereu; trimite semnalul 0. - Trimiți semnale către PID-uri vechi din fișiere
.piduitate. Numărul poate aparține acum altui proces.
Comenzi înrudite
os.Getpid: Getpid returnează ID-ul procesului curent; Getppid, ID-ul procesului care l-a pornit (părintele).signal.Notify: Trimite semnalele primite de program (Ctrl+C, SIGTERM) pe un canal, ca să le tratezi; Stop oprește trimiterea.os.StartProcess: Pornește un proces nou la nivel scăzut, cu programul, argumentele și fișierele date; de obicei folosești os/exec.exec.Cmd.Start: Start pornește comanda fără să aștepte; Wait așteaptă terminarea ei și eliberează resursele.