准备
在Linux上查询程序的pid,可以通过如下方式:
ps命令
1 2 3 4
| pi@localhost:~/study$ ps -ef | grep bluealsa root 1017 1 0 19:01 ? 00:00:00 bluealsa --profile=a2dp-source pi 2852 2393 50 19:35 pts/0 00:00:00 grep --color=auto bluealsa
|
pidof命令
1 2
| pi@localhost:~/study$ pidof bluealsa 1017
|
那么是否可以通过C代码封装成接口,方便直接在代码中调用呢?可以
首先,Linux所有进程状态信息都存储在这个目录下:/proc
,每一个数字文件夹代表一个进程。

进程文件夹下有status文件,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| pi@localhost:~/study$ cat /proc/1017/status Name: bluealsa Umask: 0022 State: S (sleeping) Tgid: 1017 Ngid: 0 Pid: 1017 PPid: 1 TracerPid: 0 Uid: 0 0 0 0 Gid: 0 0 0 0 FDSize: 128 Groups: NStgid: 1017 NSpid: 1017 NSpgid: 1017 NSsid: 1017 Kthread: 0 VmPeak: 231224 kB VmSize: 231224 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 5504 kB VmRSS: 5504 kB RssAnon: 384 kB RssFile: 5120 kB RssShmem: 0 kB VmData: 25416 kB VmStk: 132 kB VmExe: 160 kB VmLib: 7720 kB VmPTE: 84 kB VmSwap: 0 kB HugetlbPages: 0 kB CoreDumping: 0 THP_enabled: 1 untag_mask: 0xffffffffffffff Threads: 4 SigQ: 1/28918 SigPnd: 0000000000000000 ShdPnd: 0000000000000000 SigBlk: 0000000000000000 SigIgn: 0000000000001000 SigCgt: 0000000100004002 CapInh: 0000000000000000 CapPrm: 000001ffffffffff CapEff: 000001ffffffffff CapBnd: 000001ffffffffff CapAmb: 0000000000000000 NoNewPrivs: 0 Seccomp: 0 Seccomp_filters: 0 Speculation_Store_Bypass: vulnerable SpeculationIndirectBranch: unknown Cpus_allowed: f Cpus_allowed_list: 0-3 Mems_allowed: 1 Mems_allowed_list: 0 voluntary_ctxt_switches: 26 nonvoluntary_ctxt_switches: 8
|
实现
通过 /proc/<pid_dir>/status
文件内的Name字段可以获取程序名,Pid字段可以获取程序ID。逐步遍历所有这样的目标文件,将输入的程序名和Name字段的值进行比较,最后就可以得出程序的pid。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| #include <stdio.h> #include <string.h> #include <sys/types.h> #include <dirent.h> pid_t get_pid_by_name(char *task_name) { pid_t pid = 0; DIR *dir = NULL; struct dirent *ptr = NULL; FILE *fp = NULL; char filepath[512] = {0}; char cur_task_name[50] = {0}; char buf[1024] = {0}; if (NULL == task_name) return pid; dir = opendir("/proc"); if (NULL != dir) { while ((ptr = readdir(dir)) != NULL) { if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) continue; if (DT_DIR != ptr->d_type) continue; sprintf(filepath, "/proc/%s/status", ptr->d_name); fp = fopen(filepath, "r"); if (NULL != fp) { if (NULL == fgets(buf, sizeof(buf) - 1, fp)) { fclose(fp); continue; } sscanf(buf, "%*s %s", cur_task_name); if (!strcmp(task_name, cur_task_name)) { sscanf(ptr->d_name, "%d", &pid); fclose(fp); break; } fclose(fp); } } closedir(dir); } return pid; }
int main(int argc, char *argv[]) { if (2 != argc) { printf("too small params\n" "%s <program_name>\n", argv[0]); return 1; } char task_name[256] = {0}; pid_t pid = 0; sprintf(task_name, "%s", argv[1]); pid = get_pid_by_name(task_name); printf("Name: %s\n" "Pid: %d\n", task_name, pid); return 0; }
|
编译并运行程序:
1 2 3 4 5
| pi@localhost:~/study$ gcc pid_get.c -Wall -o pid_get pi@localhost:~/study$ ./pid_get bluealsa Name: bluealsa Pid: 1017
|
通过ps命令、pidof命令查询出来的bluealsa进程的pid是1017,而通过上述程序得出的bluealsa的pid也是1017,所以一切正常。