Linux的ps简单实现

原理:遍历下的/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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/214797.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《深入理解计算机系统》学习笔记 - 第四课 - 机器级别的程序

Lecture 05 Machine Level Programming I Basics 机器级别的程序 文章目录 Lecture 05 Machine Level Programming I Basics 机器级别的程序intel 处理器的历史和体系结构芯片的构成AMD 公司(Advanced Micro Devices&#xff0c;先进的微型设备) C, 汇编, 机器代码定义汇编/机器…

2024美赛备战1--数据处理(数据预处理,异常值处理,预测模型,插值拟合 *****必看****)

1.数据预处理 所谓数据预处理&#xff0c;就是指在正式做题之前对数据进行的一些处理。在有些情 况下&#xff0c;出题方提供的数据或者网上查找的数据并不能直接使用&#xff0c;比如缺少数据甚 至是异常数据&#xff0c;如果直接忽略缺失值&#xff0c;或者没发现异常数据&am…

angular material mat-error 失效不展示

1.你命名了控制mat-error显示与否的变量&#xff0c;却没有在html里使用 2.mat-error是放在mat-form-field里才生效的&#xff0c;如果 <input matInput required formControlName"phoneNumber" /> 中的phoneNumber其实是valid&#xff0c;通过验证的&#x…

【KALI】设置静态IP地址

ip: 192.168.1.10/24 网关&#xff1a;192.168.1.1 DNS&#xff1a;192.168.1.254/etc/network/interfaces原始文件内容为&#xff1a; # This file describes the network interfaces available on your system # and how to activate them. For more information, see inter…

数字图像处理(实践篇)二十一 人脸识别

目录 1 安装face_recognition 2 涉及的函数 3 人脸识别方案 4 实践 使用face_recognition进行人脸识别。 1 安装face_recognition pip install face_recognition 或者 pip --default-timeout100 install face_recognition -i http://pypi.douban.com/simple --trusted-…

川崎ZX-6R确定引进,636它真的来了,3C认证已过。

最新消息&#xff0c;兄弟们&#xff0c;你们期待已久的川崎ZX6R&#xff08;636&#xff09;基本已经确定引进了&#xff0c;官方的3C认证已经通过&#xff0c;那么从3C里面我们可以看到哪几个信息&#xff1f;产品代号ZX636J就是心心念念的ZX-6R了。 有些小伙伴不太清楚3C认…

t-SNE完整笔记 (附Python代码)

t-SNE(t-distributed stochastic neighbor embedding)是用于降维的一种机器学习算法&#xff0c;是由 Laurens van der Maaten 和 Geoffrey Hinton在08年提出来。此外&#xff0c;t-SNE 是一种非线性降维算法&#xff0c;非常适用于高维数据降维到2维或者3维&#xff0c;进行可…

laravel定时任务配置手册

任务调度在 app/Console/Kernel.php 的 schedule 方法中进行定义&#xff1b; 分配多种调度计划&#xff1a;结合其他一些特定条件&#xff0c;我们可以生成在一周中特定时间运行的任务。举个例子&#xff0c;在每周一执行命令&#xff1a; 方法 描述 ->cron(* * * * *); …

分配栈空间的三种方式(基于适配qemu的FreeRTOS分析)

1、定义全局的数组 定义的全局数组属于bss段&#xff0c;相当于把bss段的一部分作为栈空间&#xff0c;栈空间的大小就是数组的大小如果把栈空间放在bss段&#xff0c;则在bss段清零时会多清零一段地址空间 2、在链接脚本中指定 用链接脚本在所有段的后面增加stack段&#xff…

15:00面试,15:06就出来了,问的问题真变态。。。

刚从小厂出来&#xff0c;没想到在另一家公司我又寄了。 在这家公司上班&#xff0c;每天都要加班&#xff0c;但看在钱给的比较多的份上&#xff0c;也就不太计较了。但万万没想到5月一纸通知&#xff0c;所有人不准加班了&#xff0c;不仅加班费没有了&#xff0c;薪资还要降…

基于springboot的大学生兼职信息管理系统(源码+数据库+文档)

摘要 基于Spring Boot的大学生兼职信息管理系统是一个为大学生和兼职公司提供服务的平台。通过该系统&#xff0c;大学生可以方便地寻找兼职工作机会&#xff0c;而兼职公司可以发布、管理和筛选合适的兼职信息。首先&#xff0c;系统采用了Spring Boot作为开发框架&#xff0…

Ubuntu22.04使能root用户

一、背景 安装Ubuntu22.04系统的时候&#xff0c;会要求创建一个用户&#xff0c;并设置密码。为方便后续行文&#xff0c;将此用户称为user_normal&#xff0c;此密码称为normal_pd 安装Ubuntu22.04系统的时候&#xff0c;没有出现任何和root有关的设置 Ubuntu22.04安装完成…

[陇剑杯 2021]日志分析

[陇剑杯 2021]日志分析 题目做法及思路解析&#xff08;个人分享&#xff09; 问一&#xff1a;单位某应用程序被攻击&#xff0c;请分析日志&#xff0c;进行作答&#xff1a; 网络存在源码泄漏&#xff0c;源码文件名是_____________。(请提交带有文件后缀的文件名&…

前端mp3文件转wav文件的实现

一、音频文件格式转换 1&#xff09;安装fluent-ffmpeg和ffmpeg插件 npm install fluent-ffmpeg; npm install ffmpeg;2&#xff09;mp3转wav test.js文件&#xff1a; const ffmpeg require(fluent-ffmpeg);ffmpeg(./test.mp3) .format(wav) .audioBitrate(16k) .audioFre…

(纯原创) 基于SSM 的商城购物系统(完整源代码以及开发文档)

摘要 本网上商城系统以SSM架构、使用Mybatis&#xff0c;数据库使用MySQL&#xff0c;这些技术目前相对比较成熟&#xff0c;方便系统的维护与扩展。网上商城系统前台包括了用户注册、用户登录、商品查询、商品添加到购物车、删除商品等几大功能&#xff1b;后台管理功能则包…

Android VpnService 使用(一)

Android VpnService 使用(一) 本篇算是VpnService 使用的第一篇文章,主要讲述service创建,intent调用. 1: 申请权限 <service android:name".MyVpnService" android:permission"android.permission.BIND_VPN_SERVICE"><intent-filter><ac…

Android 7.1 默认自拍镜像

Android 7.1 默认自拍镜像 近来收到客户需求反馈需要将相机前摄成像默认为镜像显示&#xff0c;大致思路我们可以在保存数据前将前摄拍的照片转为镜像&#xff0c;保存数据是通过PhotoMode.java文件中的saveData方法实现&#xff0c;具体修改参照如下&#xff1a; 首先添加将图…

LeetCode力扣每日一题(Java):27、移除元素

一、题目 二、解题思路 1、我的思路 因为题目中说“元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。”也就是说&#xff1a; 输入&#xff1a;nums [3,2,2,3], val 3 输出&#xff1a;2, nums [2,2] 解释&#xff1a;函数应该返回新的长度 2并且 nums 中的…

JVM性能调优

遇到以下情况&#xff0c;就需要考虑进行JVM调优了&#xff1a; Heap内存&#xff08;老年代&#xff09;持续上涨达到设置的最大内存值&#xff1b; Full GC 次数频繁&#xff1b; GC 停顿时间过长&#xff08;超过1秒&#xff09;&#xff1b; 应用出现OutOfMemory 等内存异常…

xtts和ogg不选择?

不选择ogg的理由&#xff1a; 1.需要在源端创建用户赋权&#xff0c;启用数据库最小日志&#xff0c;附加日志等操作--对生产影响较大 2.外键约束过多&#xff0c;割接启用可能很慢https://www.modb.pro/db/201126--割接停机时间影响 3.初始化配置expdp导出可能快照过旧&#x…