kill 与killall

2023-05-16

【查询命令所属软件包】

        rpm -qf /usr/bin/killall

                psmisc-22.20-15.el7.x86_64

        rpm -qf /usr/bin/kill

                util-linux-2.23.2-65.el7_9.1.x86_64

【命令参数】

killallkill

  -e,--exact          require exact match for very long names

  -I,--ignore-case    case insensitive process name match

  -g,--process-group  kill process group instead of process

  -y,--younger-than   kill processes younger than TIME

  -o,--older-than     kill processes older than TIME

  -i,--interactive    ask for confirmation before killing

  -l,--list           list all known signal names

  -q,--quiet          don't print complaints

  -r,--regexp         interpret NAME as an extended regular expression

  -s,--signal SIGNAL  send this signal instead of SIGTERM

  -u,--user USER      kill only process(es) running as USER

  -v,--verbose        report if the signal was successfully sent

  -V,--version        display version information

  -w,--wait           wait for processes to die

  -Z,--context REGEXP kill only process(es) having context

                      (must precede other arguments)

--

【源码】

kill GitHub - util-linux/util-linux at v2.23.2

killall https://gitlab.com/psmisc/psmisc/-/tree/v22.20

killall 代码实现关键点:kill 调用,正则表达式匹配、虚拟目录(/proc/)枚举进程

/*
 * killall.c - kill processes by name or list PIDs
 *
 * Copyright (C) 1993-2002 Werner Almesberger
 * Copyright (C) 2002-2012 Craig Small
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <getopt.h>
#include <pwd.h>
#include <regex.h>
#include <ctype.h>
#include <assert.h>

#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif /*WITH_SELINUX*/

#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif /* HAVE_LOCALE_H */

#include "i18n.h"
#include "comm.h"
#include "signals.h"

#define PROC_BASE "/proc"
#define MAX_NAMES (int)(sizeof(unsigned long)*8)

#define TSECOND "s"
#define TMINUTE "m"
#define THOUR   "h"
#define TDAY    "d" 
#define TWEEK   "w"
#define TMONTH  "M" 
#define TYEAR   "y"

#define TMAX_SECOND 31536000
#define TMAX_MINUTE 525600  
#define TMAX_HOUR   8760    
#define TMAX_DAY    365     
#define TMAX_WEEK   48      
#define TMAX_MONTH  12      
#define TMAX_YEAR   1       

#define ER_REGFAIL -1
#define ER_NOMEM   -2
#define ER_UNKWN   -3
#define ER_OOFRA   -4

static int verbose = 0, exact = 0, interactive = 0, reg = 0,
           quiet = 0, wait_until_dead = 0, process_group = 0,
           ignore_case = 0;
static long younger_than = 0, older_than = 0;

static int
ask (char *name, pid_t pid, const int signal)
{
  int res;
  size_t len;
  char *line;

  line = NULL;
  len = 0;

  do {
    if (signal == SIGTERM)
        printf (_("Kill %s(%s%d) ? (y/N) "), name, process_group ? "pgid " : "",
	        pid);
    else
        printf (_("Signal %s(%s%d) ? (y/N) "), name, process_group ? "pgid " : "",
	        pid);

    fflush (stdout);

    if (getline (&line, &len, stdin) < 0)
      return 0;
    /* Check for default */
    if (line[0] == '\n') {
      free(line);
      return 0;
    }
    res = rpmatch(line);
    if (res >= 0) {
      free(line);
      return res;
    }
  } while(1);
  /* Never should get here */
}

static double
uptime()
{
   char * savelocale;
   char buf[2048];
   FILE* file;
   if (!(file=fopen( PROC_BASE "/uptime", "r"))) {
      fprintf(stderr, "killall: error opening uptime file\n");	
      exit(1);
   }
   savelocale = setlocale(LC_NUMERIC, NULL);
   setlocale(LC_NUMERIC,"C");
   if (fscanf(file, "%2047s", buf) == EOF) perror("uptime");
   fclose(file);
   setlocale(LC_NUMERIC,savelocale);
   return atof(buf);
}

/* process age from jiffies to seconds via uptime */
static double process_age(const unsigned long long jf)
{
	double age;
	double sc_clk_tck = sysconf(_SC_CLK_TCK);
	assert(sc_clk_tck > 0);
	age = uptime() - jf / sc_clk_tck;
	if (age < 0L)
		return 0L;
	return age;
}

/* returns requested time interval in seconds, 
 negative indicates error has occurred
 */
static long
parse_time_units(const char* age)
{
   char *unit;
   long num;

   num = strtol(age,&unit,10);
   if (age == unit) /* no digits found */
     return -1;
   if (unit[0] == '\0') /* no units found */
     return -1;

   switch(unit[0]) {
   case 's':
     return num;
   case 'm':
     return (num * 60);
   case 'h':
     return (num * 60 * 60);
   case 'd':
     return (num * 60 * 60 * 24);
   case 'w':
     return (num * 60 * 60 * 24 * 7);
   case 'M':
     return (num * 60 * 60 * 24 * 7 * 4);
   case 'y':
     return (num * 60 * 60 * 24 * 7 * 4 * 12);
   }
   return -1;
}

static int
match_process_uid(pid_t pid, uid_t uid)
{
	char buf[128];
	uid_t puid;
	FILE *f;
	int re = -1;
	
	snprintf (buf, sizeof buf, PROC_BASE "/%d/status", pid);
	if (!(f = fopen (buf, "r")))
		return 0;
	
	while (fgets(buf, sizeof buf, f))
	{
		if (sscanf (buf, "Uid:\t%d", &puid))
		{
			re = uid==puid;
			break;
		}
	}
	fclose(f);
	if (re==-1)
	{
		fprintf(stderr, _("killall: Cannot get UID from process status\n"));
		exit(1);
	}
	return re;
}

static regex_t *
build_regexp_list(int names, char **namelist)
{
	int i;
	regex_t *reglist;
	int flag = REG_EXTENDED|REG_NOSUB;
	
	if (!(reglist = malloc (sizeof (regex_t) * names)))
	{
		perror ("malloc");
		exit (1);
	}

	if (ignore_case)
		flag |= REG_ICASE;
	
	for (i = 0; i < names; i++)
	{
		if (regcomp(&reglist[i], namelist[i], flag) != 0) 
		{
			fprintf(stderr, _("killall: Bad regular expression: %s\n"), namelist[i]);
			exit (1);
		}
	}
	return reglist;
}

#ifdef WITH_SELINUX
static int
kill_all(int signal, int names, char **namelist, struct passwd *pwent, 
					regex_t *scontext )
#else  /*WITH_SELINUX*/
static int
kill_all (int signal, int names, char **namelist, struct passwd *pwent)
#endif /*WITH_SELINUX*/
{
  DIR *dir;
  struct dirent *de;
  FILE *file;
  struct stat st, sts[MAX_NAMES];
  int *name_len = NULL;
  char *path, comm[COMM_LEN];
  char *command_buf;
  char *command;
  pid_t *pid_table, pid, self, *pid_killed;
  pid_t *pgids;
  int i, j, okay, length, got_long, error;
  int pids, max_pids, pids_killed;
  unsigned long found;
  regex_t *reglist = NULL;;
#ifdef WITH_SELINUX
  security_context_t lcontext=NULL;
#endif /*WITH_SELINUX*/

  if (names && reg) 
      reglist = build_regexp_list(names, namelist);
  else if (names)
   {
      if (!(name_len = malloc (sizeof (int) * names)))
        {
          perror ("malloc");
          exit (1);
        }
      for (i = 0; i < names; i++) 
        {
          if (!strchr (namelist[i], '/'))
            {
	      sts[i].st_dev = 0;
	      name_len[i] = strlen (namelist[i]);
            }
          else if (stat (namelist[i], &sts[i]) < 0)
            {
	      perror (namelist[i]);
	      exit (1);
            }
        }
    } 
  self = getpid ();
  found = 0;
  if (!(dir = opendir (PROC_BASE)))
    {
      perror (PROC_BASE);
      exit (1);
    }
  max_pids = 256;
  pid_table = malloc (max_pids * sizeof (pid_t));
  if (!pid_table)
    {
      perror ("malloc");
      exit (1);
    }
  pids = 0;
  while ( (de = readdir (dir)) != NULL)
    {
      if (!(pid = (pid_t) atoi (de->d_name)) || pid == self)
	continue;
      if (pids == max_pids)
	{
	  if (!(pid_table = realloc (pid_table, 2 * pids * sizeof (pid_t))))
	    {
	      perror ("realloc");
	      exit (1);
	    }
	  max_pids *= 2;
	}
      pid_table[pids++] = pid;
    }
  (void) closedir (dir);
  pids_killed = 0;
  pid_killed = malloc (max_pids * sizeof (pid_t));
  if (!pid_killed)
    {
      perror ("malloc");
      exit (1);
    }
  if (!process_group)
    pgids = NULL;		/* silence gcc */
  else
    {
      pgids = calloc (pids, sizeof (pid_t));
      if (!pgids)
	{
	  perror ("malloc");
	  exit (1);
	}
    }
  for (i = 0; i < pids; i++)
    {
      pid_t id;
      int found_name = -1;
      double process_age_sec = 0;
      /* match by UID */
      if (pwent && match_process_uid(pid_table[i], pwent->pw_uid)==0)
	continue;
#ifdef WITH_SELINUX
      /* match by SELinux context */
      if (scontext) 
        {
          if (getpidcon(pid_table[i], &lcontext) < 0)
            continue;
	  if (regexec(scontext, lcontext, 0, NULL, 0) != 0) {
            freecon(lcontext);
            continue;
          }
          freecon(lcontext);
        }
#endif /*WITH_SELINUX*/
      /* load process name */
      if (asprintf (&path, PROC_BASE "/%d/stat", pid_table[i]) < 0)
	continue;
      if (!(file = fopen (path, "r"))) 
	{
	  free (path);
	  continue;
	}
      free (path);
      okay = fscanf (file, "%*d (%15[^)]", comm) == 1;
      if (!okay) {
	fclose(file);
	continue;
      }
      if ( younger_than || older_than ) {
	 rewind(file);
	 unsigned long long proc_stt_jf = 0;
	 okay = fscanf(file, "%*d %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %Lu", 
		       &proc_stt_jf) == 1;
	 if (!okay) {
	    fclose(file);
	    continue;
	 }
	 process_age_sec = process_age(proc_stt_jf);
      }
      (void) fclose (file);
       
      got_long = 0;
      command = NULL;		/* make gcc happy */
      length = strlen (comm);
      if (length == COMM_LEN - 1)
	{
	  if (asprintf (&path, PROC_BASE "/%d/cmdline", pid_table[i]) < 0)
	    continue;
	  if (!(file = fopen (path, "r"))) {
	    free (path);
	    continue;
	  }
	  free (path);
          while (1) {
            /* look for actual command so we skip over initial "sh" if any */
            char *p;
	    int cmd_size = 128;
	    command_buf = (char *)malloc (cmd_size);
	    if (!command_buf)
	      exit (1);

            /* 'cmdline' has arguments separated by nulls */
            for (p=command_buf; ; p++) {
              int c;
	      if (p == (command_buf + cmd_size)) 
		{
		  int cur_size = cmd_size;
		  cmd_size *= 2;
		  command_buf = (char *)realloc(command_buf, cmd_size);
		  if (!command_buf)
		    exit (1);
		  p = command_buf + cur_size;
		}
              c = fgetc(file);
              if (c == EOF || c == '\0') {
                *p = '\0';
                break;
              } else {
                *p = c;
              }
            }
            if (strlen(command_buf) == 0) {
              okay = 0;
              break;
            }
            p = strrchr(command_buf,'/');
            p = p ? p+1 : command_buf;
            if (strncmp(p, comm, COMM_LEN-1) == 0) {
              okay = 1;
              command = p;
              break;
            }
          }
          (void) fclose(file);
	  if (exact && !okay)
	    {
	      if (verbose)
		fprintf (stderr, _("killall: skipping partial match %s(%d)\n"),
			comm, pid_table[i]);
	      continue;
	    }
	  got_long = okay;
	}
      /* mach by process name */
      for (j = 0; j < names; j++)
	{
	  if (reg)
	    {
	      if (regexec (&reglist[j], got_long ? command : comm, 0, NULL, 0) != 0)
		      continue;
	    }
	  else /* non-regex */
	    {
	      if ( younger_than && process_age_sec && (process_age_sec > younger_than ) )
		 continue;
	      if ( older_than   && process_age_sec && (process_age_sec < older_than ) )
		 continue;
	       
 	      if (!sts[j].st_dev)
	        {
	          if (length != COMM_LEN - 1 || name_len[j] < COMM_LEN - 1)
	  	    {
		      if (ignore_case == 1)
		        {
		          if (strcasecmp (namelist[j], comm))
		             continue;
		        }
		      else
		        {
		          if (strcmp(namelist[j], comm))
		             continue;
		        }
		    }
	          else
	            {
	              if (ignore_case == 1)
	                {
	                  if (got_long ? strcasecmp (namelist[j], command) :
	                                 strncasecmp (namelist[j], comm, COMM_LEN - 1))
	                     continue;
	                }
	              else
	                {
	                  if (got_long ? strcmp (namelist[j], command) :
	                                 strncmp (namelist[j], comm, COMM_LEN - 1))
	                     continue;
	                }
	            }
	        }
	      else
	        {
		  int ok = 1;

	          if (asprintf (&path, PROC_BASE "/%d/exe", pid_table[i]) < 0)
		    continue;

	          if (stat (path, &st) < 0) 
		      ok = 0;

		  else if (sts[j].st_dev != st.st_dev ||
			   sts[j].st_ino != st.st_ino)
		    {
		      /* maybe the binary has been modified and std[j].st_ino
		       * is not reliable anymore. We need to compare paths.
		       */
		      size_t len = strlen(namelist[j]);
		      char *linkbuf = malloc(len + 1);

		      if (!linkbuf ||
			  readlink(path, linkbuf, len + 1) != len ||
			  memcmp(namelist[j], linkbuf, len))
			ok = 0;
		      free(linkbuf);
		    }

		  free(path);
		  if (!ok)
		    continue;
	        }
	    } /* non-regex */
	  found_name = j;
	  break;
	}  
        
        if (names && found_name==-1)
	  continue;  /* match by process name faild */
	
        /* check for process group */
	if (!process_group)
	  id = pid_table[i];
	else
	  {
	    int j;

	    id = getpgid (pid_table[i]);
	    pgids[i] = id;
	    if (id < 0)
	      {
	        fprintf (stderr, "killall: getpgid(%d): %s\n",
			   pid_table[i], strerror (errno));
	      }
	    for (j = 0; j < i; j++)
	      if (pgids[j] == id)
	        break;
	    if (j < i)
	      continue;
	  }	
	if (interactive && !ask (comm, id, signal))
	  continue;
	if (kill (process_group ? -id : id, signal) >= 0)
	  {
	    if (verbose)
	      fprintf (stderr, _("Killed %s(%s%d) with signal %d\n"), got_long ? command :
			 comm, process_group ? "pgid " : "", id, signal);
	    if (found_name >= 0)
		    /* mark item of namelist */
		    found |= 1 << found_name;
	    pid_killed[pids_killed++] = id;
	  }
	else if (errno != ESRCH || interactive)
	  fprintf (stderr, "%s(%d): %s\n", got_long ? command :
	    	comm, id, strerror (errno));
    }
  if (!quiet)
    for (i = 0; i < names; i++)
      if (!(found & (1 << i)))
	fprintf (stderr, _("%s: no process found\n"), namelist[i]);
  if (names)
    /* killall returns a zero return code if at least one process has 
     * been killed for each listed command. */
    error = found == ((1 << (names - 1)) | ((1 << (names - 1)) - 1)) ? 0 : 1;
  else
    /* in nameless mode killall returns a zero return code if at least 
     * one process has killed */
    error = pids_killed ? 0 : 1;
  /*
   * We scan all (supposedly) killed processes every second to detect dead
   * processes as soon as possible in order to limit problems of race with
   * PID re-use.
   */
  while (pids_killed && wait_until_dead)
    {
      for (i = 0; i < pids_killed;)
	{
	  if (kill (process_group ? -pid_killed[i] : pid_killed[i], 0) < 0 &&
	      errno == ESRCH)
	    {
	      pid_killed[i] = pid_killed[--pids_killed];
	      continue;
	    }
	  i++;
	}
      sleep (1);		/* wait a bit longer */
    }
  return error;
}


static void
usage (const char *msg)
{
  if (msg != NULL)
    fprintf(stderr, "%s\n", msg);
#ifdef WITH_SELINUX
   fprintf(stderr, _(
     "Usage: killall [-Z CONTEXT] [-u USER] [ -eIgiqrvw ] [ -SIGNAL ] NAME...\n"));
#else  /*WITH_SELINUX*/
  fprintf(stderr, _(
    "Usage: killall [OPTION]... [--] NAME...\n"));
#endif /*WITH_SELINUX*/
  fprintf(stderr, _(
    "       killall -l, --list\n"
    "       killall -V, --version\n\n"
    "  -e,--exact          require exact match for very long names\n"
    "  -I,--ignore-case    case insensitive process name match\n"
    "  -g,--process-group  kill process group instead of process\n"
    "  -y,--younger-than   kill processes younger than TIME\n"
    "  -o,--older-than     kill processes older than TIME\n"		    
    "  -i,--interactive    ask for confirmation before killing\n"
    "  -l,--list           list all known signal names\n"
    "  -q,--quiet          don't print complaints\n"
    "  -r,--regexp         interpret NAME as an extended regular expression\n"
    "  -s,--signal SIGNAL  send this signal instead of SIGTERM\n"
    "  -u,--user USER      kill only process(es) running as USER\n"
    "  -v,--verbose        report if the signal was successfully sent\n"
    "  -V,--version        display version information\n"
    "  -w,--wait           wait for processes to die\n"));
#ifdef WITH_SELINUX
  fprintf(stderr, _(
    "  -Z,--context REGEXP kill only process(es) having context\n"
    "                      (must precede other arguments)\n"));
#endif /*WITH_SELINUX*/
  fputc('\n', stderr);
  exit(1);
}


void print_version()
{
  fprintf(stderr, "killall (PSmisc) %s\n", VERSION);
  fprintf(stderr, _(
    "Copyright (C) 1993-2012 Werner Almesberger and Craig Small\n\n"));
  fprintf(stderr, _(
    "PSmisc comes with ABSOLUTELY NO WARRANTY.\n"
    "This is free software, and you are welcome to redistribute it under\n"
    "the terms of the GNU General Public License.\n"
    "For more information about these matters, see the files named COPYING.\n"));
}

static int
have_proc_self_stat (void)
{
  char filename[128];
  struct stat isproc;
  pid_t pid = getpid();

  snprintf(filename, sizeof(filename), PROC_BASE"/%d/stat", (int) pid);
  return stat(filename, &isproc) == 0;
}

int
main (int argc, char **argv)
{
  char *name;
  int sig_num;
  int optc;
  int myoptind;
  struct passwd *pwent = NULL;
  char yt[16];
  char ot[16];

  //int optsig = 0;

  struct option options[] = {
    {"exact", 0, NULL, 'e'},
    {"ignore-case", 0, NULL, 'I'},
    {"process-group", 0, NULL, 'g'},
    {"younger-than", 1, NULL, 'y'},
    {"older-than", 1, NULL, 'o'},
    {"interactive", 0, NULL, 'i'},
    {"list-signals", 0, NULL, 'l'},
    {"quiet", 0, NULL, 'q'},
    {"regexp", 0, NULL, 'r'},
    {"signal", 1, NULL, 's'},
    {"user", 1, NULL, 'u'},
    {"verbose", 0, NULL, 'v'},
    {"wait", 0, NULL, 'w'},
#ifdef WITH_SELINUX
    {"context", 1, NULL, 'Z'},
#endif /*WITH_SELINUX*/
    {"version", 0, NULL, 'V'},
    {0,0,0,0 }};

  /* Setup the i18n */
#ifdef ENABLE_NLS
  setlocale(LC_ALL, "");
  bindtextdomain(PACKAGE, LOCALEDIR);
  textdomain(PACKAGE);
#endif
#ifdef WITH_SELINUX
  security_context_t scontext = NULL;
  regex_t scontext_reg;

  if ( argc < 2 ) usage(NULL); /* do the obvious thing... */
#endif /*WITH_SELINUX*/

  name = strrchr (*argv, '/');
  if (name)
    name++;
  else
    name = *argv;
  sig_num = SIGTERM;


  opterr = 0;
#ifdef WITH_SELINUX
  while ( (optc = getopt_long_only(argc,argv,"egy:o:ilqrs:u:vwZ:VI",options,NULL)) != -1) {
#else
  while ( (optc = getopt_long_only(argc,argv,"egy:o:ilqrs:u:vwVI",options,NULL)) != -1) {
#endif
    switch (optc) {
    case 'e':
      exact = 1;
      break;
    case 'g':
      process_group = 1;
      break;
    case 'y':
      strncpy(yt, optarg, 16);
	  yt[15] = '\0';
      if ( 0 >= (younger_than = parse_time_units(yt) ) )
	    usage(_("Invalid time format"));
      break;
    case 'o':
      strncpy(ot, optarg, 16);
	  ot[15] = '\0';
      if ( 0 >= (older_than = parse_time_units(ot) ) )
	    usage(_("Invalid time format"));
      break;
    case 'i':
      interactive = 1;
      break;
    case 'l':
      list_signals();
      return 0;
      break;
    case 'q':
      quiet = 1;
      break;
    case 'r':
	  reg = 1;
	  break;
    case 's':
	  sig_num = get_signal (optarg, "killall");
      break;
    case 'u':
      if (!(pwent = getpwnam(optarg))) {
        fprintf (stderr, _("Cannot find user %s\n"), optarg);
        exit (1);
      }
      break;
    case 'v':
      verbose = 1;
      break;
    case 'w':
      wait_until_dead = 1;
      break;
    case 'I':
      /* option check is optind-1 but sig name is optind */
      if (strcmp(argv[optind-1],"-I") == 0 || strncmp(argv[optind-1],"--",2) == 0) {
        ignore_case = 1;
      } else {
	      sig_num = get_signal (argv[optind]+1, "killall");
      }
      break;
    case 'V':
      /* option check is optind-1 but sig name is optind */
      if (strcmp(argv[optind-1],"-V") == 0 || strncmp(argv[optind-1],"--",2) == 0) {
        print_version();
        return 0;
      }
	    sig_num = get_signal (argv[optind]+1, "killall");
      break;
#ifdef WITH_SELINUX
    case 'Z': 
      if (is_selinux_enabled()>0) {
	    scontext=optarg;
        if (regcomp(&scontext_reg, scontext, REG_EXTENDED|REG_NOSUB) != 0) {
          fprintf(stderr, _("Bad regular expression: %s\n"), scontext);
          exit (1);
	    }
      } else 
        fprintf(stderr, "Warning: -Z (--context) ignored. Requires an SELinux enabled kernel\n");
      break;
#endif /*WITH_SELINUX*/
    case '?':
      /* Signal names are in uppercase, so check to see if the argv
       * is upper case */
      if (argv[optind-1][1] >= 'A' && argv[optind-1][1] <= 'Z') {
	    sig_num = get_signal (argv[optind-1]+1, "killall");
      } else {
        /* Might also be a -## signal too */
        if (argv[optind-1][1] >= '0' && argv[optind-1][1] <= '9') {
          sig_num = atoi(argv[optind-1]+1);
        } else {
          usage(NULL);
        }
      }
      break;
    }
  }
  myoptind = optind;
#ifdef WITH_SELINUX
  if ((argc - myoptind < 1) && pwent==NULL && scontext==NULL) 
#else
  if ((argc - myoptind < 1) && pwent==NULL)	  
#endif
    usage(NULL);

  if (argc - myoptind > MAX_NAMES) {
    fprintf (stderr, _("killall: Maximum number of names is %d\n"),
	   MAX_NAMES);
    exit (1);
  }
  if (!have_proc_self_stat()) {
    fprintf (stderr, _("killall: %s lacks process entries (not mounted ?)\n"),
		PROC_BASE);
    exit (1);
  }
  argv = argv + myoptind;
  /*printf("sending signal %d to procs\n", sig_num);*/
#ifdef WITH_SELINUX
  return kill_all(sig_num,argc - myoptind, argv, pwent, 
		  		scontext ? &scontext_reg : NULL);
#else  /*WITH_SELINUX*/
  return kill_all(sig_num,argc - myoptind, argv, pwent);
#endif /*WITH_SELINUX*/
}

kill 代码关键点:kill 调用

/*
 * Copyright (c) 1988, 1993, 1994
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
/*
 *  oct 5 1994 -- almost entirely re-written to allow for process names.
 *  modifications (c) salvatore valente <svalente@mit.edu>
 *  may be used / modified / distributed under the same terms as the original.
 *
 *  1999-02-22 Arkadiusz Miśkiewicz <misiek@pld.ORG.PL>
 *  - added Native Language Support
 *
 *  1999-11-13 aeb Accept signal numers 128+s.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>		/* for isdigit() */
#include <unistd.h>
#include <signal.h>

#include "c.h"
#include "nls.h"
#include "closestream.h"
#include "procutils.h"
#include "strutils.h"
#include "ttyutils.h"
#include "xalloc.h"

struct signv {
	const char *name;
	int val;
} sys_signame[] = {
	/* POSIX signals */
	{ "HUP",	SIGHUP },	/* 1 */
	{ "INT",	SIGINT }, 	/* 2 */
	{ "QUIT",	SIGQUIT }, 	/* 3 */
	{ "ILL",	SIGILL }, 	/* 4 */
#ifdef SIGTRAP
	{ "TRAP",	SIGTRAP },	/* 5 */
#endif
	{ "ABRT",	SIGABRT }, 	/* 6 */
#ifdef SIGIOT
	{ "IOT",	SIGIOT }, 	/* 6, same as SIGABRT */
#endif
#ifdef SIGEMT
	{ "EMT",	SIGEMT }, 	/* 7 (mips,alpha,sparc*) */
#endif
#ifdef SIGBUS
	{ "BUS",	SIGBUS },	/* 7 (arm,i386,m68k,ppc), 10 (mips,alpha,sparc*) */
#endif
	{ "FPE",	SIGFPE }, 	/* 8 */
	{ "KILL",	SIGKILL }, 	/* 9 */
	{ "USR1",	SIGUSR1 }, 	/* 10 (arm,i386,m68k,ppc), 30 (alpha,sparc*), 16 (mips) */
	{ "SEGV",	SIGSEGV }, 	/* 11 */
	{ "USR2",	SIGUSR2 }, 	/* 12 (arm,i386,m68k,ppc), 31 (alpha,sparc*), 17 (mips) */
	{ "PIPE",	SIGPIPE }, 	/* 13 */
	{ "ALRM",	SIGALRM }, 	/* 14 */
	{ "TERM",	SIGTERM }, 	/* 15 */
#ifdef SIGSTKFLT
	{ "STKFLT",	SIGSTKFLT },	/* 16 (arm,i386,m68k,ppc) */
#endif
	{ "CHLD",	SIGCHLD }, 	/* 17 (arm,i386,m68k,ppc), 20 (alpha,sparc*), 18 (mips) */
#ifdef SIGCLD
	{ "CLD",	SIGCLD },	/* same as SIGCHLD (mips) */
#endif
	{ "CONT",	SIGCONT }, 	/* 18 (arm,i386,m68k,ppc), 19 (alpha,sparc*), 25 (mips) */
	{ "STOP",	SIGSTOP },	/* 19 (arm,i386,m68k,ppc), 17 (alpha,sparc*), 23 (mips) */
	{ "TSTP",	SIGTSTP },	/* 20 (arm,i386,m68k,ppc), 18 (alpha,sparc*), 24 (mips) */
	{ "TTIN",	SIGTTIN },	/* 21 (arm,i386,m68k,ppc,alpha,sparc*), 26 (mips) */
	{ "TTOU",	SIGTTOU },	/* 22 (arm,i386,m68k,ppc,alpha,sparc*), 27 (mips) */
#ifdef SIGURG
	{ "URG",	SIGURG },	/* 23 (arm,i386,m68k,ppc), 16 (alpha,sparc*), 21 (mips) */
#endif
#ifdef SIGXCPU
	{ "XCPU",	SIGXCPU },	/* 24 (arm,i386,m68k,ppc,alpha,sparc*), 30 (mips) */
#endif
#ifdef SIGXFSZ
	{ "XFSZ",	SIGXFSZ },	/* 25 (arm,i386,m68k,ppc,alpha,sparc*), 31 (mips) */
#endif
#ifdef SIGVTALRM
	{ "VTALRM",	SIGVTALRM },	/* 26 (arm,i386,m68k,ppc,alpha,sparc*), 28 (mips) */
#endif
#ifdef SIGPROF
	{ "PROF",	SIGPROF },	/* 27 (arm,i386,m68k,ppc,alpha,sparc*), 29 (mips) */
#endif
#ifdef SIGWINCH
	{ "WINCH",	SIGWINCH },	/* 28 (arm,i386,m68k,ppc,alpha,sparc*), 20 (mips) */
#endif
#ifdef SIGIO
	{ "IO",		SIGIO },	/* 29 (arm,i386,m68k,ppc), 23 (alpha,sparc*), 22 (mips) */
#endif
#ifdef SIGPOLL
	{ "POLL",	SIGPOLL },	/* same as SIGIO */
#endif
#ifdef SIGINFO
	{ "INFO",	SIGINFO },	/* 29 (alpha) */
#endif
#ifdef SIGLOST
	{ "LOST",	SIGLOST }, 	/* 29 (arm,i386,m68k,ppc,sparc*) */
#endif
#ifdef SIGPWR
	{ "PWR",	SIGPWR },	/* 30 (arm,i386,m68k,ppc), 29 (alpha,sparc*), 19 (mips) */
#endif
#ifdef SIGUNUSED
	{ "UNUSED",	SIGUNUSED },	/* 31 (arm,i386,m68k,ppc) */
#endif
#ifdef SIGSYS
	{ "SYS",	SIGSYS }, 	/* 31 (mips,alpha,sparc*) */
#endif
};

static int arg_to_signum (char *arg, int mask);
static void nosig (char *name);
static void printsig (int sig);
static void printsignals (FILE *fp, int pretty);
static int usage (int status);
static int kill_verbose (char *procname, int pid, int sig);

#ifdef HAVE_SIGQUEUE
static int use_sigval;
static union sigval sigdata;
#endif

int main (int argc, char *argv[])
{
    int errors, numsig, pid;
    char *ep, *arg;
    int do_pid, do_kill, check_all;

    setlocale(LC_ALL, "");
    bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);
    atexit(close_stdout);

    numsig = SIGTERM;
    do_pid = (! strcmp (program_invocation_short_name, "pid")); 	/* Yecch */
    do_kill = 0;
    check_all = 0;

    /*  loop through the arguments.
	actually, -a is the only option can be used with other options.
	`kill' is basically a one-option-at-most program.  */
    for (argc--, argv++; argc > 0; argc--, argv++) {
	arg = *argv;
	if (*arg != '-') {
	    break;
	}
	if (! strcmp (arg, "--")) {
	    argc--, argv++;
	    break;
	}
	if (! strcmp (arg, "-v") || ! strcmp (arg, "-V") ||
	    ! strcmp (arg, "--version")) {
	    printf(UTIL_LINUX_VERSION);
	    return EXIT_SUCCESS;
	}
	if (! strcmp (arg, "-h") || ! strcmp (arg, "--help"))
	    return usage(EXIT_FAILURE);

	if (! strcmp (arg, "-a") || ! strcmp (arg, "--all")) {
	    check_all++;
	    continue;
	}
	if (! strcmp (arg, "-l") || ! strcmp (arg, "--list")) {
	    if (argc < 2) {
		printsignals (stdout, 0);
		return EXIT_SUCCESS;
	    }
	    if (argc > 2)
		return usage (EXIT_FAILURE);
	    /* argc == 2, accept "kill -l $?" */
	    arg = argv[1];
	    if ((numsig = arg_to_signum (arg, 1)) < 0)
		errx(EXIT_FAILURE, _("unknown signal: %s"), arg);
	    printsig (numsig);
	    return EXIT_SUCCESS;
	}
	/* for compatibility with procps kill(1) */
	if (! strncmp (arg, "--list=", 7) || ! strncmp (arg, "-l=", 3)) {
		char *p = strchr(arg, '=') + 1;
		if ((numsig = arg_to_signum(p, 1)) < 0)
			errx(EXIT_FAILURE, _("unknown signal: %s"), p);
		printsig (numsig);
		return EXIT_SUCCESS;
	}
	if (! strcmp (arg, "-L") || ! strcmp (arg, "--table")) {
	    printsignals (stdout, 1);
	    return EXIT_SUCCESS;
	}
	if (! strcmp (arg, "-p") || ! strcmp (arg, "--pid")) {
	    do_pid++;
	    if (do_kill)
		return usage (EXIT_FAILURE);
	    continue;
	}
	if (! strcmp (arg, "-s") || ! strcmp (arg, "--signal")) {
	    if (argc < 2) {
		return usage (EXIT_FAILURE);
	    }
	    do_kill++;
	    if (do_pid)
		return usage (EXIT_FAILURE);
	    argc--, argv++;
	    arg = *argv;
	    if ((numsig = arg_to_signum (arg, 0)) < 0) {
		nosig (arg);
		return EXIT_FAILURE;
	    }
	    continue;
	}
	if (! strcmp (arg, "-q") || ! strcmp (arg, "--queue")) {
	    if (argc < 2)
		return usage (EXIT_FAILURE);
	    argc--, argv++;
	    arg = *argv;
#ifdef HAVE_SIGQUEUE
	    sigdata.sival_int = strtos32_or_err(arg, _("invalid sigval argument"));
	    use_sigval = 1;
#endif
	    continue;
	}
	/*  `arg' begins with a dash but is not a known option.
	    so it's probably something like -HUP, or -1/-n
	    try to deal with it.
	    -n could be signal n, or pid -n (i.e. process group n).
	    In case of doubt POSIX tells us to assume a signal.
	    If a signal has been parsed, assume it's a pid, break */
	if (do_kill)
	  break;
	arg++;
	if ((numsig = arg_to_signum (arg, 0)) < 0) {
	    return usage (EXIT_FAILURE);
	}
	do_kill++;
	if (do_pid)
	    return usage (EXIT_FAILURE);
	continue;
    }

    if (! *argv) {
	return usage (EXIT_FAILURE);
    }
    if (do_pid) {
	numsig = -1;
    }

    /*  we're done with the options.
	the rest of the arguments should be process ids and names.
	kill them.  */
    for (errors = 0; (arg = *argv) != NULL; argv++) {
	pid = strtol (arg, &ep, 10);
	if (! *ep)
	    errors += kill_verbose (arg, pid, numsig);
	else  {
	    struct proc_processes *ps = proc_open_processes();
	    int ct = 0;

	    if (!ps)
	        continue;

	    if (!check_all)
		proc_processes_filter_by_uid(ps, getuid());

	    proc_processes_filter_by_name(ps, arg);

	    while (proc_next_pid(ps, &pid) == 0) {
		errors += kill_verbose(arg, pid, numsig);
		ct++;
	    }

	    if (!ct) {
		errors++;
		warnx (_("cannot find process \"%s\""), arg);
	    }
	    proc_close_processes(ps);
	}
    }
    if (errors != 0)
	errors = EXIT_FAILURE;
    return errors;
}

#ifdef SIGRTMIN
static int rtsig_to_signum(char *sig)
{
	int num, maxi = 0;
	char *ep = NULL;

	if (strncasecmp(sig, "min+", 4) == 0)
		sig += 4;
	else if (strncasecmp(sig, "max-", 4) == 0) {
		sig += 4;
		maxi = 1;
	}

	if (!isdigit(*sig))
		return -1;

	errno = 0;
	num = strtol(sig, &ep, 10);
	if (!ep || sig == ep || errno || num < 0)
		return -1;

	num = maxi ? SIGRTMAX - num : SIGRTMIN + num;

	if (num < SIGRTMIN || num > SIGRTMAX)
		return -1;

	return num;
}
#endif

static int signame_to_signum (char *sig)
{
    size_t n;

    if (! strncasecmp (sig, "sig", 3))
	sig += 3;

#ifdef SIGRTMIN
    /* RT signals */
    if (!strncasecmp(sig, "rt", 2))
	return rtsig_to_signum(sig + 2);
#endif
    /* Normal sugnals */
    for (n = 0; n < ARRAY_SIZE(sys_signame); n++) {
	if (! strcasecmp (sys_signame[n].name, sig))
	    return sys_signame[n].val;
    }
    return (-1);
}

static int arg_to_signum (char *arg, int maskbit)
{
    int numsig;
    char *ep;

    if (isdigit (*arg)) {
	numsig = strtol (arg, &ep, 10);
	if (numsig >= NSIG && maskbit && (numsig & 128) != 0)
	    numsig -= 128;
	if (*ep != 0 || numsig < 0 || numsig >= NSIG)
	    return (-1);
	return (numsig);
    }
    return signame_to_signum (arg);
}

static void nosig (char *name)
{
    warnx (_("unknown signal %s; valid signals:"), name);
    printsignals (stderr, 1);
}

static void printsig (int sig)
{
    size_t n;

    for (n = 0; n < ARRAY_SIZE(sys_signame); n++) {
	if (sys_signame[n].val == sig) {
	    printf ("%s\n", sys_signame[n].name);
	    return;
	}
    }
#ifdef SIGRTMIN
    if (sig >= SIGRTMIN && sig <= SIGRTMAX) {
	printf ("RT%d\n", sig - SIGRTMIN);
	return;
    }
#endif
    printf("%d\n", sig);
}

#define FIELD_WIDTH 11
static void pretty_print_signal(FILE *fp, size_t term_width, size_t *lpos,
				int signum, const char *name)
{
	if (term_width < (*lpos + FIELD_WIDTH)) {
	    fputc ('\n', fp);
	    *lpos = 0;
	}
	*lpos += FIELD_WIDTH;
	fprintf (fp, "%2d %-8s", signum, name);
}

static void printsignals (FILE *fp, int pretty)
{
    size_t n, lth, lpos = 0, width;

    if (!pretty) {
	for (n = 0; n < ARRAY_SIZE(sys_signame); n++) {
	    lth = 1+strlen(sys_signame[n].name);
	    if (lpos+lth > 72) {
		fputc ('\n', fp);
		lpos = 0;
	    } else if (lpos)
		fputc (' ', fp);
	    lpos += lth;
	    fputs (sys_signame[n].name, fp);
	}
#ifdef SIGRTMIN
	fputs (" RT<N> RTMIN+<N> RTMAX-<N>", fp);
#endif
	fputc ('\n', fp);
	return;
    }
    /* pretty print */
    width = get_terminal_width();
    if (width == 0)
	width = 72;
    else
	width -= 1;

    for (n = 0; n < ARRAY_SIZE(sys_signame); n++)
	    pretty_print_signal(fp, width, &lpos,
			    sys_signame[n].val, sys_signame[n].name);

#ifdef SIGRTMIN
    pretty_print_signal(fp, width, &lpos, SIGRTMIN, "RTMIN");
    pretty_print_signal(fp, width, &lpos, SIGRTMAX, "RTMAX");
#endif
    fputc ('\n', fp);
}

static int usage(int status)
{
	FILE *out = (status == 0 ? stdout : stderr);

	fputs(USAGE_HEADER, out);
	fprintf(out, _(" %s [options] <pid|name> [...]\n"), program_invocation_short_name);
	fputs(USAGE_OPTIONS, out);
	fputs(_(" -a, --all              do not restrict the name-to-pid conversion to processes\n"
		"                        with the same uid as the present process\n"), out);
	fputs(_(" -s, --signal <sig>     send specified signal\n"), out);
	fputs(_(" -q, --queue <sig>      use sigqueue(2) rather than kill(2)\n"), out);
	fputs(_(" -p, --pid              print pids without signaling them\n"), out);
	fputs(_(" -l, --list [=<signal>] list signal names, or convert one to a name\n"), out);
	fputs(_(" -L, --table            list signal names and numbers\n"), out);
	fputs(USAGE_SEPARATOR, out);
	fputs(USAGE_HELP, out);
	fputs(USAGE_VERSION, out);
	fprintf(out, USAGE_MAN_TAIL("kill(1)"));

	return status;
}

static int kill_verbose (char *procname, pid_t pid, int sig)
{
    int rc = 0;

    if (sig < 0) {
	printf ("%ld\n", (long)pid);
	return 0;
    }
#ifdef HAVE_SIGQUEUE
    if (use_sigval)
	rc = sigqueue(pid, sig, sigdata);
    else
#endif
	rc = kill (pid, sig);

    if (rc < 0) {
	warn(_("sending signal to %s failed"), procname);
	return 1;
    }
    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

kill 与killall 的相关文章

  • 单片机蓝桥杯--数码管显示

    我们先来看一下蓝桥杯板中数码管部分的电路图 对于动态数码管的控制 是需要有段选和位选的 位选是控制数码管哪一位显示 段选是控制该位显示什么数字 由上图可知 当Y6C有效时 P0控制的是数码管的位 当Y7C有效时 可以给P0写入显示数字的断码
  • linux信号通信总结

    http www ibm com developerworks cn linux l ipc part2 index1 html http www ibm com developerworks cn linux l ipc part2 in
  • ORACLE如何停止一个JOB

    ORACLE如何停止一个JOB 1 相关表 视图 dba jobs all jobs user jobs 包含登录用户所有的JOB信息 dba jobs running 包含正在运行job相关信息 注意 须使用oracle的sys用户登录到
  • Socket编程中的强制关闭与优雅关闭及相关socket选项

    以下描述主要是针对windows平台下的TCP socket而言 首先需要区分一下关闭socket和关闭TCP连接的区别 关闭TCP连接是指TCP协议层的东西 就是两个TCP端之间交换了一些协议包 FIN RST等 具体的交换过程可以看TC
  • 杀死java中的无限循环

    我正在使用第三方库来处理大量数据集 该过程偶尔会进入无限循环 或被阻塞 不知道为什么并且无法进入代码 我想在设定的时间后杀死它并继续下一个案例 一个简单的例子是 for Object data dataList Object result
  • 自动 Killall 然后 Killall 9 级

    有时我想killall某个进程 但正在运行killall不起作用 因此 当我尝试再次启动该进程时 它会失败 因为前一个会话仍在运行 然后我就得无聊的跑killall 9在上面 所以为了简化我的生活 我创建了一个realkill脚本 它是这样
  • 当收到来自“killall”或“kill -p pid”的终止信号时,如何在退出程序之前执行处理程序函数?

    我有以下代码 include
  • 如何在 C++ 中杀死进程,只知道其名称的一部分

    前段时间我需要编写 C 代码来终止某些进程 在我的主程序中 我使用 system 运行大型 CAE 系统包 并在输入上使用不同的文件名字符串 CAE 软件创建许多进程 其中包含进程名称字符串filename 一些CAE过程worktime
  • Android:检查活动是否被系统从服务中销毁

    我有一项服务监听来自服务器的一些事件 服务有 START STICKY 标志 当它被操作系统杀死时 该标志使他重新启动 当服务收到事件时 我有两种情况 首先 如果活动没有被终止 我需要将结果发送到本地广播接收器并更新 UI 其次 如果它被操
  • GNU 屏幕没有响应,似乎被阻止

    GNU 屏幕似乎冻结了 无法输入用户输入 我正在使用 GNU 屏幕 当我按下屏幕时 它变得没有响应 我可以执行所有 GNU 屏幕命令 但无法输入用户输入 我不想关闭这个屏幕 因为我有重要的工作 我不想失去它 In the commands
  • 当 Perl 中发生警报时,我应该如何清理挂起的孙进程?

    我有一个并行自动化脚本 需要调用许多其他脚本 其中一些脚本挂起 因为它们 错误地 等待标准输入或等待各种其他不会发生的事情 这没什么大不了的 因为我抓住那些alarm http perldoc perl org functions alar
  • 使用子进程时如何限制程序的执行时间?

    我想使用子进程来运行程序 并且需要限制执行时间 例如 如果它运行超过2秒我想杀死它 对于普通程序 kill 效果很好 但如果我尝试跑步 usr bin time something kill 并不能真正杀死程序 我下面的代码似乎不能很好地工
  • GC 暂停和终止 -STOP 会产生相同的行为吗?

    我看到 Java 客户端应用程序在现场崩溃 我认为这是因为它连接的服务器经历了 12 秒的完整 GC 暂停 但是 当我尝试在 Eclipse 中本地运行客户端 服务器并使用kill STOP 和kill CONT 重现行为以模拟服务器上的G
  • cygwin中如何杀死进程?

    您好 我有以下无法杀死的进程 我在 windows xp 32 位中运行 cygwin 我尝试发出以下命令 bin kill f 4760 bin kill 9 5000 kill 9 5000 kill 5000 当我写 bin kill
  • 如何杀死shell的所有子进程?

    我正在编写一个 bash 脚本 它可以完成几件事 一开始它会启动几个监视脚本 每个脚本都运行一些其他工具 在我的主脚本结束时 我想杀死从我的外壳中产生的所有东西 所以 它可能看起来像这样 bin bash some monitor1 sh
  • 当终止使用 python 子进程 Popen 启动的进程时,如何关闭标准输出管道?

    我想知道当杀死在不同线程中启动的子进程时是否可以关闭通信管道 如果我不调用communicate 那么kill 将按预期工作 在一秒而不是五秒后终止进程 我发现了类似问题的讨论here http bugs python org issue4
  • 如何杀死 ubuntu 上端口上的进程

    我正在尝试在命令行中终止 ubuntu 中特定端口的进程 如果我运行此命令 我会得到端口 sudo lsof t i 9001 所以 现在我想运行 sudo kill sudo lsof t i 9001 我收到此错误消息 ERROR ga
  • GDB可以杀死一个特定的线程吗?

    我正在运行一个应用程序 firefox 我想知道是否可以使用 GDB 附加到进程并杀死特定线程 有没有办法做到这一点 我知道此操作可能会使应用程序崩溃 EDIT 在此调试会话中 ps ax显示firefox pid是1328 gdb App
  • 杀死 OpenCL 内核

    有没有办法通过 OpenCL API 终止正在运行的 OpenCL 内核 我在规范中没有找到任何内容 我能想到的唯一解决方案是 1 定期检查内核中主机希望内核停止时写入的标志 或 2 在单独的进程中运行内核并终止整个进程 我认为这两个都不是
  • 为什么我无法杀死 k8s pod 中的 python 进程?

    我试图杀死一个 python 进程 ps aux grep python root 1 12 6 2 1 2234740 1332316 Ssl 20 04 19 36 usr bin python3 batch run py root 4

随机推荐

  • C++中的qsort、sort排序

    注意 xff1a int char string之类的是可以之间使用 gt lt 61 61 之类的进行判断 xff0c char 类型的使用strcmp就行了 而struct与vector都可以当做数组进行处理 xff0c cmp函数传递
  • 迷宫问题(牛客)

    题目描述 xff1a 定义一个二维数组N M xff08 其中2 lt 61 N lt 61 10 2 lt 61 M lt 61 10 xff09 xff0c 如5 5数组下所示 xff1a int maze 5 5 61 0 1 0 0
  • 查找兄弟单词(牛客)

    题目描述 xff1a 兄弟单词 xff1a 给定一个单词X xff0c 如果通过任意交换单词中字母的位置得到的新的单词Y xff0c 那么称X和Y是兄弟单词 注意 xff1a bca和abc是兄弟单词 xff0c abc和abc是相同单词
  • 合唱团(牛客)

    题目描述 xff1a 计算最少出列多少位同学 xff0c 使得剩下的同学排成合唱队形 说明 xff1a N位同学站成一排 xff0c 音乐老师要请其中的 N K 位同学出列 xff0c 使得剩下的K位同学排成合唱队形 合唱队形是指这样的一种
  • 字符串排序(牛客)

    题目描述 xff1a 编写一个程序 xff0c 将输入字符串中的字符按如下规则排序 规则 1 xff1a 英文字母从 A 到 Z 排列 xff0c 不区分大小写 如 xff0c 输入 xff1a Type 输出 xff1a epTy 规则
  • 字符串加密(牛客)

    题目描述 xff1a 有一种技巧可以对数据进行加密 xff0c 它使用一个单词作为它的密匙 下面是它的工作原理 xff1a 首先 xff0c 选择一个单词作为密匙 xff0c 如TRAILBLAZERS 如果单词中包含有重复的字母 xff0
  • 统计每个月兔子的总数(牛客)

    题目描述 xff1a 有一只兔子 xff0c 从出生后第3个月起每个月都生一只兔子 xff0c 小兔子长到第三个月后每个月又生一只兔子 xff0c 假如兔子都不死 xff0c 问每个月的兔子总数为多少 xff1f 输入描述 xff1a 输入
  • 购物单(牛客)(01背包+分组背包+有依赖的背包)

    题目描述 xff1a 王强今天很开心 xff0c 公司发给N元的年终奖 王强决定把年终奖用于购物 xff0c 他把想买的物品分为两类 xff1a 主件与附件 xff0c 附件是从属于某个主件的 xff0c 下表就是一些主件与附件的例子 xf
  • gmssl 生成SM2证书、加密、解密、签名、验签

    1 生成SM2密钥对 gmssl ecparam genkey name sm2p256v1 out sm2keypair pem text 2 查看SM2密钥对 gmssl ec in sm2keypair pem text 3 生成自签
  • 求小球落地5次后所经历的路程和第五次反弹的高度(牛客)

    题目描述 xff1a 假设一个球从任意高度自由落下 xff0c 每次落地后反跳回原高度的一半 再落下 求它在第5次落地时 xff0c 共经历多少米 第5次反弹多高 xff1f 最后的误差判断是小数点6位 输入描述 xff1a 输入起始高度
  • 输入一行字符,分别统计出包含英文字符、空格、数字和其他字符的个数(牛客)

    题目描述 xff1a 输入一行字符 xff0c 分别统计出包含英文字母 空格 数字和其它字符的个数 输入描述 xff1a 输入一行字符串 xff0c 可以有空格 1qazxsw23 edcvfr45tgbn hy67uj m ki89ol
  • 字符串合并处理(牛客)

    题目描述 xff1a 按照指定规则对输入的字符串进行处理 详细描述 xff1a 将输入的两个字符串合并 对合并后的字符串进行排序 xff0c 要求为 xff1a 下标为奇数的字符和下标为偶数的字符分别从小到大排序 这里的下标意思是字符在字符
  • 蛇形矩阵(牛客)

    题目描述 xff1a 蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形 输入描述 xff1a 输入正整数N xff08 N不大于100 xff09 5 输出描述 xff1a 输出一个N行的蛇形矩阵 1 3 6 10 15 2 5 9
  • 图片整理(牛客)

    题目描述 xff1a Lily上课时使用字母数字图片教小朋友们学习英语单词 xff0c 每次都需要把这些图片按照大小 xff08 ASCII码值从小到大 xff09 排列收好 请大家给Lily帮忙 xff0c 通过C语言解决 输入描述 xf
  • 单词倒排(牛客)

    题目描述 xff1a 对字符串中的所有单词进行倒排 说明 xff1a 1 构成单词的字符只有26个大写或小写英文字母 xff1b 2 非构成单词的字符均视为单词间隔符 xff1b 3 要求倒排后的单词间隔符以一个空格表示 xff1b 如果原
  • 字符串运用-密码截取(牛客)

    题目描述 xff1a xff08 最大回文序列 xff09 Catcher是MCA国的情报员 xff0c 他工作时发现敌国会用一些对称的密码进行通信 xff0c 比如像这些ABBA xff0c ABA xff0c A xff0c 12332
  • 字符串加解密(牛客)

    题目描述 xff1a 1 对输入的字符串进行加解密 xff0c 并输出 2加密方法为 xff1a 当内容是英文字母时则用该英文字母的后一个字母替换 xff0c 同时字母变换大小写 如字母a时则替换为B xff1b 字母Z时则替换为a xff
  • 表达式求值(牛客)

    题目描述 xff1a 给定一个字符串描述的算术表达式 xff0c 计算出结果值 输入字符串长度不超过100 xff0c 合法的字符包括 43 xff0c 0 9 xff0c 字符串内容的合法性及表达式语法的合法性由做题者检查 本题目只涉及整
  • 02 vue框架内部的各种指令和axios操作的代码详解

    目录 前言 第一个完整的Vue程序 el xff1a 挂载点 和 data xff1a 数据对象 v text指令 v html指令 v on指令 v show指令 v if指令 v bind指令 v for指令 v on指令补充 v mo
  • kill 与killall

    查询命令所属软件包 rpm qf usr bin killall psmisc 22 20 15 el7 x86 64 rpm qf usr bin kill util linux 2 23 2 65 el7 9 1 x86 64 命令参数