Linux下通过进程名获得进程号

来源:互联网 发布:windows 任务计划程序 编辑:程序博客网 时间:2024/04/26 06:57

因为存在多进程和线程,Linux下同一个进程名有可能有多个进程号。下面的程序可以一次获得同一进程名的所有进程号。


process.h

#ifndef __PROCESS_H__#define __PROCESS_H__char *basename(const char *path);int get_pid_by_name(const char* process_name, pid_t pid_list[], int list_size);int is_process_exist(const char* process_name);#endif /* __PROCESS_H__ */

process.c (使用/proc/pid/exe 查找进程名有时候会有问题,比如busybox中的命令,查到的是busybox)

修改为使用/proc/pid/cmdline来查找。

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/types.h>#include <dirent.h>#include <ctype.h>#include <errno.h>char *basename(const char *path){register const char *s;register const char *p;p = s = path;while (*s) {if (*s++ == '/') {p = s;}}return (char *) p;}/* find all pid of process by name, only compare base name of pid_name  * pid_list: caller malloc pid_t array  * list_size: the size of pid_list  * RETURN:  *        < 0: error number  *        >=0: how many pid found, pid_list will store the founded pid  */int get_pid_by_name(const char* process_name, pid_t pid_list[], int list_size){#define  MAX_BUF_SIZE       256    DIR *dir;    struct dirent *next;    int count=0;    pid_t pid;    FILE *fp;    char *base_pname = NULL;    char *base_fname = NULL;    char cmdline[MAX_BUF_SIZE];    char path[MAX_BUF_SIZE];    if(process_name == NULL || pid_list == NULL)        return -EINVAL;    base_pname = basename(process_name);    if(strlen(base_pname) <= 0)        return -EINVAL;    dir = opendir("/proc");    if (!dir)    {        return -EIO;    }    while ((next = readdir(dir)) != NULL) {        /* skip non-number */        if (!isdigit(*next->d_name))            continue;        pid = strtol(next->d_name, NULL, 0);        sprintf(path, "/proc/%u/cmdline", pid);        fp = fopen(path, "r");        if(fp == NULL)            continue;        memset(cmdline, 0, sizeof(cmdline));        if(fread(cmdline, MAX_BUF_SIZE - 1, 1, fp) < 0){             fclose(fp);            continue;        }        fclose(fp);        base_fname = basename(cmdline);        if (strcmp(base_fname, base_pname) == 0 )        {            if(count >= list_size){                break;            }else{                pid_list[count] = pid;                count++;            }        }    }    closedir(dir) ;    return count;}/* If process is existed, return true */int is_process_exist(const char* process_name){    pid_t pid;    return (get_pid_by_name(process_name, &pid, 1) > 0);}

main.c

#include <stdlib.h>#include <stdio.h>#include "process.h"#define MAX_PID_NUM     32int main(int argc, char* argv[]){  char* process;  int ret = 0;  int n;  pid_t pid[MAX_PID_NUM];  if(argc < 2)    process = argv[0];  else    process = argv[1];  ret = get_pid_by_name(process, pid, MAX_PID_NUM);  printf("process '%s' is existed? (%d): %c\n", process, ret, (ret > 0)?'y':'n');  for(n=0;n<ret;n++){    printf("%u\n", pid[n]);  }  return ret;}


Makefile:

PROG=check_processOBJS=process.o main.o#CFLAGS = -g -ggdball:$(PROG)check_process:$(OBJS)$(CC) -o $@ $^ $(LDFLAGS)%.o:%.c$(CC) -c -o $@ $(CFLAGS) $<clean:rm -rf $(PROG) *.o