func (m *Monitor) Unsubscribe(c chan runc.Exit) {
	m.Lock()
	s, ok := m.subscribers[c]
	if !ok {
		m.Unlock()
		return
	}
	s.close()
	delete(m.subscribers, c)
	m.Unlock()
}
Unsubscribe to process exit changes
package reaper
import (
	"os/exec"
	"sync"
	"time"
	runc "github.com/containerd/go-runc"
	"github.com/pkg/errors"
	"golang.org/x/sys/unix"
)
var ErrNoSuchProcess = errors.New("no such process")
const bufferSize = 32
type subscriber struct {
	sync.Mutex
	c      chan runc.Exit
	closed bool
}
func (s *subscriber) close() {
	s.Lock()
	if s.closed {
		s.Unlock()
		return
	}
	close(s.c)
	s.closed = true
	s.Unlock()
}
func (s *subscriber) do(fn func()) {
	s.Lock()
	fn()
	s.Unlock()
}
func Reap() error {
	now := time.Now()
	exits, err := reap(false)
	for _, e := range exits {
		done := Default.notify(runc.Exit{
			Timestamp: now,
			Pid:       e.Pid,
			Status:    e.Status,
		})
		select {
		case <-done:
		case <-time.After(1 * time.Second):
		}
	}
	return err
}
var Default = &Monitor{
	subscribers: make(map[chan runc.Exit]*subscriber),
}
type Monitor struct {
	sync.Mutex
	subscribers map[chan runc.Exit]*subscriber
}
func (m *Monitor) Start(c *exec.Cmd) (chan runc.Exit, error) {
	ec := m.Subscribe()
	if err := c.Start(); err != nil {
		m.Unsubscribe(ec)
		return nil, err
	}
	return ec, nil
}
func (m *Monitor) Wait(c *exec.Cmd, ec chan runc.Exit) (int, error) {
	for e := range ec {
		if e.Pid == c.Process.Pid {
			c.Wait()
			m.Unsubscribe(ec)
			return e.Status, nil
		}
	}
	return -1, ErrNoSuchProcess
}
func (m *Monitor) Subscribe() chan runc.Exit {
	c := make(chan runc.Exit, bufferSize)
	m.Lock()
	m.subscribers[c] = &subscriber{
		c: c,
	}
	m.Unlock()
	return c
}