2013-03-04 2 views
12

프로세스의 PID가있는 경우 os.FindProcess이면 프로세스를 테스트 할 수 있습니까? 내 말은 그것이 err을 반환한다면 그것이 종결되었다고 가정 할 수 있습니까?진행중인 프로세스가 있는지 확인하십시오.

편집 :

난 그냥 래퍼 함수 주위 kill -s 0 (이전 스타일의 bash 프로세스 테스트)를 작성했습니다. os.FindProcess 것이 아무 문제없이 작동하지만 다른 솔루션이 문제 : (등 리눅스, FreeBSD의) 시스템과 같은 UNIX에서

func checkPid(pid int) bool { 
    out, err := exec.Command("kill", "-s", "0", strconv.Itoa(pid)).CombinedOutput() 
    if err != nil { 
     log.Println(err) 
    } 

    if string(out) == "" { 
     return true // pid exist 
    } 
    return false 
} 

답변

26

이 프로세스가 살아 있는지 확인하기 위해 기존의 유닉스 방법입니다 - 그것을 보내 0의 시그널 (bash 예제에서와 같이).

kill(2)에서

:

If sig is 0, then no signal is sent, but error checking is still per‐ 
    formed; this can be used to check for the existence of a process ID or 
    process group ID. 

그리고 당신은 당신이 (123)가 죽었다는 그 과정을 보여주는이 얻을 그것을 실행하면 이동

package main 

import (
    "fmt" 
    "log" 
    "os" 
    "strconv" 
    "syscall" 
) 

func main() { 
    for _, p := range os.Args[1:] { 
     pid, err := strconv.ParseInt(p, 10, 64) 
     if err != nil { 
      log.Fatal(err) 
     } 
     process, err := os.FindProcess(int(pid)) 
     if err != nil { 
      fmt.Printf("Failed to find process: %s\n", err) 
     } else { 
      err := process.Signal(syscall.Signal(0)) 
      fmt.Printf("process.Signal on pid %d returned: %v\n", pid, err) 
     } 

    } 
} 

로 번역 과정 1은 살아 있지만 귀하가 소유하고있는 프로세스 12606은 귀하가 소유하고 소유하고 있습니다.

$ ./kill 1 $$ 123 
process.Signal on pid 1 returned: operation not permitted 
process.Signal on pid 12606 returned: <nil> 
process.Signal on pid 123 returned: no such process 
+0

그게 전부 야! 이동 방법을 보여 주셔서 감사합니다 :) –

+0

왜 당신은'int64'로 구문 분석하고 있습니다. 'Atoi'가 더 좋지 않습니까 ('FindProcess'에서 타입 변환 안함)? – tjameson

+0

네가 맞다. '아토이'가 더 좋을 것이다. 나는 최근에'ParseInt'를 사용하여 그것을 잊어 버렸습니다. –

5

에 (이동 도서관으로 수행)이 있다면 난 여전히 행복 해요 오류를 반환하지 않습니다. Windows에서 어떤 일이 발생하는지 모르겠습니다. 즉, * os.Process를 사용하기 전까지는 PID가 올바른지 알 수 없습니다.

코드 here을 볼 수 있습니다.

+0

맞아.항상 사실을 알려주고 해결 방법을 찾았습니다. (위의 편집을보십시오) –

+0

Windows 10에서 저의 경험에 따르면, 주어진 PID를 가진 프로세스가 실행되고 있지 않으면'os.FindProcess'는 에러를 반환합니다. – Kerrmiter

1

이전에 알려진 pid가 시스템에 없으면 (이동 기능이 확실하지 않은 경우) 프로세스가 완전히 종료되었고 (Unix에서는 wait call) 조인되었음을 의미합니다.

그러나 그 밖의 다른 방법은 반드시 사실 일 수는 없습니다. pid가 있기 때문에 이전과 동일한 프로세스이므로 quarantee가 아닙니다. 예를 들어, 표준 Linux에는 65535 개의 유효한 pid가 있으며, 랩 어라운드가있을 때 재사용 할 수 있습니다. 그러나 실제로 자주 확인하는 경우 실제적인 목적을 위해이 작업을 신경 쓸 필요가 없습니다 (잘못된 새로운 프로세스가 발견되면 보안 취약점 또는 기타 심각한 문제가 아닌 한 누군가가 의도적으로 악의적으로 트리거하려고 시도 할 수 있습니다. 목적). (권리 열에 및 관련 질문)

관련 링크 :

+0

나는 한 번 이상 upvote 수 있습니다. pid가 재사용된다는 관찰은 현대 하드웨어에서 프로세스를 안정적으로 모니터하고자하는 모든 사람들에게 매우 중요합니다. 오작동하고 다시 생성되는 경우 pid 네임 스페이스가 빨리 소모됩니다. 스레드 ID는 프로세스 ID와 동일한 네임 스페이스에 있기 때문에 스레드가 많은 프로세스는 문제를 악화시킵니다. – Mark

+1

추가 정보 ... 추가 신뢰가 필요하면 $ pid에 대한 [프로세스 시작 시간] (http://unix.stackexchange.com/a/7871/158521)이 검사 사이에 변경되지 않았는지 확인하십시오. 있다면, 그것은 다른 과정입니다. 그렇지 않은 경우, 매우 다른 프로세스가 될 가능성은 희박합니다. – Mark

+0

"매우있을 법하지 않음"이란 무엇입니까? 어떤 상황에서 다른 프로세스가 될 수 없습니까? 프로세스가 시작 시간이 무엇이든 상관없이 프로세스의 한 단위보다 오래 지속되었다고 가정합니다 (PID 랩 어라운드를 사용한 빠른 다이/재생성은 검사기를 혼동하지 않았습니다). 생각할 수있는 유일한 상황은 시작 시간입니다. 다른 사람들이 있습니까? –

2

syscall.Kill도 사용할 수 있습니다. 코드가 적습니다. Windows가 os.FindProcess()의 결과를 확인에

killErr := syscall.Kill(pid, syscall.Signal(0)) 
procExists := killErr == nil 
+0

[Nick Craig-Wood의 대답] (http://stackoverflow.com/a/15210305/55504)의 메모를 제외하고는 nil이 아닌 오류 기존 프로세스에 대해 리턴 될 수 있습니다. 조건이 더 복잡해야합니다 (아마'err == nil || err == syscall.EPERM', 아마 더 많이). –

0

는 프로세스가 실행되고 있는지 확인하기에 충분한 것 같다.

func isProcessRunning(pid int) bool { 
    _, err = os.FindProcess(pid) 
    if err != nil { 
     return false 
    } 
    if runtime.GOOS == "windows" { 
     return true 
    } 
    return false // further checking for other systems then Windows is not supported here 
} 
관련 문제