2016-03-17 28 views
7

Tôi có một ứng dụng trong Go để định tuyến lại STDIN và STDOUT của các tệp nhị phân và sau đó chạy chúng. Tóm lại tôi đang làm:Golang: Quá trình con trở thành Zombies

- create command object with the binary path (lets call the object command A) - create command object with the binary path (calling it command B) - set the stdout of command B to the stdin of Command A - start command A - start command B

tôi nhận thấy bất cứ khi nào quy trình thoát lệnh B trong khi lệnh A được chạy, nó trở thành một quá trình zombie trong bảng quá trình.

Dưới đây là một ví dụ:

commandA := exec.Command("samplebin") 
commandB := exec.Command("sample2bin") 

cmdAStdin := commandA.StdinPipe() 

commandB.Stdout = cmdAStdin 

commandA.Start() 
commandB.Start() 

Tại sao commandB trở thành một Zombie nếu nó thoát trong khi commandA vẫn chạy? Tôi đang chạy Go 1.5 trên Ubuntu 14.

Trả lời

11

Khi quá trình thoát, nó LUÔN LUÔN trở thành một zombie, bất kể những quá trình khác đang chạy. Đó chỉ là cách chấm dứt quá trình hoạt động. Quá trình này sẽ vẫn là một zombie cho đến khi cha mẹ gọi wait để có được trạng thái thoát của nó, hoặc chỉ ra rằng nó là không quan tâm đến trẻ em bằng cách bỏ qua SIGCHLD (có thể đã được trước khi đứa trẻ đã thoát). Nó sẽ vẫn là một zombie cho đến khi điều đó xảy ra, vì sợ rằng tình trạng thoát khỏi bị mất.

Trong ví dụ của bạn, có vẻ như quy trình của bạn (quy trình tạo quy trình) là phụ huynh, vì vậy cả A và B sẽ vẫn là zombie cho đến khi quá trình của bạn thu thập chúng.

Nếu quá trình thoát trong khi vẫn có con (hoặc chạy hoặc zombie), những trẻ này sẽ được gửi lại cho cha mẹ của quá trình thoát, thường sẽ bỏ qua trạng thái thoát (xóa các thây ma).

+0

Vì vậy, SIGCHLD được gửi bởi quy trình con ngay trước khi chúng trở thành Zombies? Sau đó, làm thế nào để "bỏ qua" SIGCHLD? Bằng cách bắt tín hiệu và không làm gì cả? – AJPennster

+0

SIGCHLD được gửi bởi hạt nhân khi một đứa trẻ như là một phần của làm cho nó một zombie. Nếu bạn muốn bỏ qua SIGCHLD và vẫn nhận được zombie, hãy đặt hành động SIGCHLD thành SIG_DFL (mặc định) thay vì SIG_IGN - hành động mặc định là không làm gì cả, nhưng vẫn nhận được zombie. –

+0

Tôi không muốn các Zombies, tôi muốn các quá trình thoát được làm sạch. Tôi đã thử thiết lập các tín hiệu trong ứng dụng chính để bỏ qua SIGCHLD và vẫn tạo ra các thây ma vì vậy tôi sẽ gọi Wait(). – AJPennster

2

Đồng ý với câu trả lời đầu tiên thoát khỏi quy trình trở thành zombie cho đến khi quá trình này được chờ đợi bởi một quy trình khác. Đây là cách tôi xử lý mọi thứ trong đi.

package main 

import (
    "bytes" 
    "io" 
    "os" 
    "os/exec" 
) 

func main() { 
    c1 := exec.Command("samplebin") 
    c2 := exec.Command("sample2bin") 

    r, w := io.Pipe() 
    c1.Stdout = w 
    c2.Stdin = r 

    var b2 bytes.Buffer 
    c2.Stdout = &b2 

    // Writing without a reader will deadlock so write in a goroutine 
    go func() { 
     // Close the writer or the pipe will not be closed for c2 
     defer w.Close() 
     defer c1.Wait() 
     c1.Start() 
    }() 
    defer c2.Wait() 
    c2.Start() 
    io.Copy(os.Stdout, &b2) 
} 
Các vấn đề liên quan