江门城乡建设局官方网站,建设网站烧钱,网页升级未成年人自行离开,做网站横幅技巧原理#xff1a;遍历下的/proc/%s/task/%s/status所有文件#xff0c;两个%s都为pid号。 注#xff1a;多线程下#xff0c;只打印一个pid/task下的所有目录#xff0c;即可收集各个线程对应的信息。
$ cat ps.c
#include stdio.h
#include stdlib.h
#in…原理遍历下的/proc/%s/task/%s/status所有文件两个%s都为pid号。 注多线程下只打印一个pid/task下的所有目录即可收集各个线程对应的信息。
$ cat ps.c
#include stdio.h
#include stdlib.h
#include string.h
#include sys/types.h
#include sys/stat.h
#include unistd.h
#include dirent.h
#include fcntl.h
#define MAX 1024
#define PATH_SIZE 128char *print_char(char *str, int length)
{static char buf[MAX] {0};int i strlen(str);int j 0;memset(buf, 0, strlen(buf));for (i 0; i length; i) {/* 跳过‘\t’输出状态信息 */if (str[i] || str[i] \t|| str[i] \n || str[i] \r) {continue;}buf[j] str[i];}buf[j] 0;return buf;
}void open_file_and_print_info(const char *path)
{char buf[MAX] {0};FILE *fp NULL;const char *title NULL;//printf(path: %s\n, path);/* 打开文件 */fp fopen(path, r);if (fp NULL) {perror(Failed to open path);exit(1);}/* 读取每一行 */while (fgets(buf, MAX, fp) ! NULL) {title Name:;if(strncmp(buf, title, strlen(title)) 0) {printf(%-40.40s,print_char(buf[strlen(title)], strlen(buf) - strlen(title)));continue;}title Pid:;if (strncmp(buf, title, strlen(title)) 0) {printf(%-10.10s,print_char(buf[strlen(title)], strlen(buf) - strlen(title)));continue;}title Cpus_allowed_list:;if (strncmp(buf, title, strlen(title)) 0) {printf(%-10.10s,print_char(buf[strlen(title)], strlen(buf) - strlen(title)));printf(\n);continue;}}/* 关闭stattus文件 */fclose(fp);
}void handle_dir(const char *dir_name)
{DIR *dir NULL;struct dirent *entry NULL;char file[PATH_SIZE] {0};/* 打开目录 */if ((dir opendir(dir_name)) NULL) {perror(fail to open dir);return;}while ((entry readdir(dir)) ! NULL) {/* 跳过当前目录 */if (entry-d_name[0] .) {continue;}/* 跳过系统信息目录所有进程的目录全都是数字而系统信息目录全都不是数字 */if ((entry-d_name[0] 0 ) || (entry-d_name[0] 9)) {continue;}/* 使用sprintf完成拼接路径其中%s会由entry-d_name表示的子线程ID替代 */memset(file, 0, strlen(file));snprintf(file, strlen(file) - 1, %s/%s/status, dir_name, entry-d_name);open_file_and_print_info(file);}/* 关闭目录 */closedir(dir);
}int main(int argc, char *argv[])
{DIR *dir NULL;struct dirent *entry NULL;char path[PATH_SIZE] {0};/* 输出表头 */printf(%-40.40s%-10.10s%-10.10s\n, NAME, PID, CPU_LIST);/* 打开/proc目录 */if ((dir opendir(/proc)) NULL ) {perror(Failed to open dir);return -1;}while ((entry readdir(dir)) ! NULL) {/* 跳过当前目录proc目录没有父目录 */if (entry-d_name[0] .) {continue;}/* 跳过系统信息目录所有进程的目录全都是数字而系统信息目录全都不是数字 */if ((entry-d_name[0] 0 ) || (entry-d_name[0] 9)) {continue;}memset(path, 0, strlen(path));
#if 0/* 使用sprintf完成拼接路径其中两个%s会由entry-d_name表示的进程ID替代 */snprintf(path, strlen(path) - 1, /proc/%s/task/%s/status, entry-d_name,entry-d_name);open_file_and_print_info(path);
#else/* 使用sprintf完成拼接路径其中%s会由entry-d_name表示的进程ID替代 */snprintf(path, strlen(path) - 1, /proc/%s/task, entry-d_name);handle_dir(path);
#endif}/* 关闭目录 */closedir( dir );return 0;
}
编译
$ gcc ps.c -o ps运行
$ ./ps
NAME PID CPU_LIST
systemd 1 0-5
kthreadd 2 0-5
rcu_gp 3 0-5
rcu_par_gp 4 0-5
kworker/0:0H 6 0
mm_percpu_wq 8 0-5
rcu_sched 10 0-5
migration/0 11 0
idle_inject/0 12 0