'Send a signal to the subprocess.  This may or may not kill it.
Return None if the signal was sent, or an error message string
if an error occurred or if the subprocess is not running.'

def kill(self, sig):

    now = time.time()
    options = self.config.options
    if (self.state == ProcessStates.BACKOFF):
        msg = ('Attempted    to    kill    %s,    which    is    in    BACKOFF    state.' % (self.config.name,))
        options.logger.debug(msg)
        self.change_state(ProcessStates.STOPPED)
        return None
    if (not self.pid):
        msg = ("attempted    to    kill    %s    with    sig    %s    but    it    wasn't    running" % (self.config.name, signame(sig)))
        options.logger.debug(msg)
        return msg
    if (self.state == ProcessStates.STOPPING):
        killasgroup = self.config.killasgroup
    else:
        killasgroup = self.config.stopasgroup
    as_group = ''
    if killasgroup:
        as_group = 'process    group    '
    options.logger.debug(('killing    %s    (pid    %s)    %swith    signal    %s' % (self.config.name, self.pid, as_group, signame(sig))))
    self.killing = True
    self.delay = (now + self.config.stopwaitsecs)
    self._assertInState(ProcessStates.RUNNING, ProcessStates.STARTING, ProcessStates.STOPPING)
    self.change_state(ProcessStates.STOPPING)
    pid = self.pid
    if killasgroup:
        pid = (- self.pid)
    try:
        options.kill(pid, sig)
    except:
        tb = traceback.format_exc()
        msg = ('unknown    problem    killing    %s    (%s):%s' % (self.config.name, self.pid, tb))
        options.logger.critical(msg)
        self.change_state(ProcessStates.UNKNOWN)
        self.pid = 0
        self.killing = False
        self.delay = 0
        return msg
    return None
