根据进程名获取进程id

在Linux操作系统中,/proc是一个虚拟文件系统,用于存储进程和用户信息。通过查看/proc/N/status文件,可以获取到进程ID为N的进程详细状态,包括进程名。当需要根据进程名查找PID时,可以遍历/proc目录下的所有子目录,找出对应进程名的PID。如果存在多个同名进程,通常只返回第一个匹配的PID。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原理:
linux操作系统中有一个名为/proc的虚拟文件系统,其中记录着进程和用户的相关信息,其中/proc/N (注:N表示数字)目录表示进程ip号为N的进程信息,就是这里找到我们要找的进程信息,其中/proc/N/status记录了进程状态信息,包含进程名等,比如:
root@proc # cat /proc/3544/status
Name: lighttpd
State: S (sleeping)
Tgid: 3544
Pid: 3544
PPid: 1
TracerPid: 0
Uid: 500 500 500 500
Gid: 500 500 500 500
Utrace: 0
FDSize: 32
Groups: 500
VmPeak: 2980 kB
VmSize: 2976 kB
。。。。。

注:对于存在多个同名的进程,只返回第一个进程ip,而不返回所有的进程ip

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>

static void getProcessName(const int pid, char *pid_name, int pid_size);
/*return:
 *      -1 not found
 *      not-negative is pid number
 *      writed by zhj 
 * */
int getPidByName(const char *name)
{
    DIR *dir_p = NULL;
    struct dirent entry, *res = NULL;
    int pid = -1, error_ret = 0;
    if(name == NULL)
    {
        return -1;
    }

    dir_p = opendir("/proc");
    if(NULL == dir_p)
    {
        printf("opendir error: %s\n", strerror(errno));
        goto ERR;
    }
    for(;;)
    {
        error_ret = readdir_r(dir_p, &entry, &res);
        if(error_ret != 0)
        {
            printf("readdir_r error: %s\n", strerror(error_ret));
            goto ERR;
        }
        if(res == NULL)
        {
            break;
        }
        if(isdigit(res->d_name[0]))
        {
            char pid_name[56] = "";

            pid = atoi(res->d_name);

            getProcessName(pid, pid_name, sizeof(pid_name));
            if(pid_name[0] != '\0' && strcmp(pid_name, name) == 0)
            {
                break;
            }
        }
        pid = -1;
    }


    if(dir_p != NULL)
    {
        closedir(dir_p);
        dir_p = NULL;
    }
    return pid;
ERR:
    if(dir_p != NULL)
    {
        closedir(dir_p);
        dir_p = NULL;
    }
    return -1;
}


static void getProcessName(const int pid, char *pid_name, int pid_size)
{
    int fd = -1;
    char name[56] = "", *p = NULL, str[56] = "", buf[1024] = "";
    int size = 0;
    struct stat file_stat;

    pid_name[0] = '\0';
    size = snprintf(name, sizeof(name) - 1, "/proc/%d/status", pid);
    if(size <= 0 || size > sizeof(name) - 1)
    {
        printf("%s %d, snprintf error\n", __func__, __LINE__);
        goto ERR;
    }

    fd = open(name, O_RDONLY);  
    if(fd < 0)
    {
        printf("%s %d, open error: %s\n", __func__, __LINE__, strerror(errno));
        goto ERR;
    }
    if(fstat(fd, &file_stat) < 0)
    {
        printf("fstat error: %s\n", strerror(errno));
        goto ERR;
    }
    size = read(fd, buf, sizeof(buf) - 1);
    if(size <= 0)
    {
        printf("read error: %s\n", strerror(errno));
        goto ERR;
    }
    buf[size] = '\0';

    if(sscanf(buf, "%s %s", str, pid_name) != 2)    
    {
        goto ERR;
    }

    if(fd != -1)
    {
        close(fd);
        fd = -1;
    }

    return ;
ERR:
    if(fd !=  -1)
    {
        close(fd);
        fd = -1;
    }

    return ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值