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 128

char *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.mfbz.cn/a/237067.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HCIA-H12-811题目解析(10)

1、【单选题】DHCP客户端在租期到达哪个比例时第一次发送续租报文&#xff1f; 2、【单选题】在WLAN中用于标识无线网络&#xff0c; 区分不同的无线网络的是&#xff1f; 3、【单选题】我们在笔记本电脑上搜索可接入无线网络时&#xff0c;显示出来的网络名称实际是 4、【单…

哪些原因导致MES管理系统实施项目失败

在制造业中&#xff0c;实施MES管理系统是一种提高生产效率、降低成本、提升质量的重要手段。然而&#xff0c;许多MES管理系统实施项目并未取得预期的成功&#xff0c;甚至失败。本文将探讨导致MES管理系统实施项目失败的原因。 1、需求不明确 在MES实施项目中&#xff0c;需…

Java-异常(一)-异常的概述和常见异常的举例

&#x1f436;b站视频 124-异常处理-异常的概述与常见异常的举例_哔哩哔哩_bilibili 目录 b站视频 5.1 异常概念 5.2 Error 示例代码 5.3 Exception异常划分 ❓面试题&#xff1a;常见的异常有哪些&#xff1f;举例说明 &#x1f436;5.1 异常概念 在使用计算机语言进行…

基于SSM的校园心理健康网站的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

PostGIS学习教程十二:地理

PostGIS学习教程十二&#xff1a;地理 坐标为"地理&#xff08;geographics&#xff09;“形式或者说是” 纬度&#xff08;latitude&#xff09;/经度&#xff08;longitude&#xff09;"形式的数据非常常见。 与Mercator&#xff08;墨卡托&#xff09;、UTM&…

【jitterbuffer】2:OnCompleteFrameCallback 送去FrameBuffer 处理的流程

【jitterbuffer】2:OnCompleteFrameCallback 送去FrameBuffer 处理的流程 基于m98版本。 WebRtc Video Receiver(六)-FrameBuffer原理 大神有个详细的论述。 Finder的FID设计 H.264 没有FID,使用RtpSeqNumOnlyRefFinder ,比较复杂,要做出决定 RtpSeqNumOnlyRefFinder cla…

canvas 有趣的弹簧效果

先上效果 两个小球之间有一根弹簧&#xff0c;这里有一条线表示&#xff0c;其中左球固定&#xff0c;在点击开始后&#xff0c;右球开始做自由落体 思路 先做受力分析 经过受力分析可以发现&#xff0c;整个系统一共有三个力在起作用&#xff0c;我们分别把他们求出来并合成…

鸿蒙原生应用再添新丁!同花顺入局鸿蒙

鸿蒙原生应用再添新丁&#xff01;同花顺入局鸿蒙 来自 HarmonyOS 微博12月11日消息&#xff0c;同花顺已完成#鸿蒙原生应用#beta版本&#xff0c;并正在进行全量版本开发&#xff0c;进一步丰富了#鸿蒙原生应用#的覆盖领域。同花顺作为股民和券商首选的一站式金融理财服务平台…

搜集怎么绘制三维曲线和曲面?

1、针对函数对象是单一变量、两个函数的情况。用plot3函数&#xff1b;&#xff08;三维曲线&#xff09; 看一下matlab官方的例子&#xff1a; t 0:pi/50:10*pi; st sin(t); ct cos(t); plot3(st,ct,t) 绘制出来的曲线&#xff1a; 几个比较关键的点&#xff1a; &…

Linux系统编程(一):基本概念

参考引用 Unix和Linux操作系统有什么区别&#xff1f;一文带你彻底搞懂posix Linux系统编程&#xff08;文章链接汇总&#xff09; 1. Unix 和 Linux 1.1 Unix Unix 操作系统诞生于 1969 年&#xff0c;贝尔实验室发布了一个用 C 语言编写的名为「Unix」的操作系统&#xff0…

nginx中的正则表达式及location和rewrite

目录 常用的Nginx 正则表达式 location和rewrite的区别 location location 大致可以分为三类 location 常用的匹配规则 location 优先级 location 示例说明 location优先级的总结 rewrite rewrite的功能 rewrite实现跳转的条件 rewrite的执行顺序 rewrite的语法格式…

C# 任务的异常和延续处理

写在前面 当Task在执行过程中出现异常或被取消等例外的情况时&#xff0c;为了让执行流程能够继续进行&#xff0c;可以使用延续方法实现这种链式处理&#xff1b;还可以针对前置任务不同的执行结果&#xff0c;选择执行不同的延续分支方法。子任务执行过程中的任何异常都会被…

【收获】成长之路

目录 一、前言二、计算机方面三、专业知识方面四、总结 一、前言 四年&#xff0c;对于一个人的成长来说&#xff0c;是一个相当重要的阶段。在这段时间里&#xff0c;我经历了许多挑战、收获了许多成就&#xff0c;也在不断地成长和改变。回首这四年的点点滴滴&#xff0c;我深…

linux docker 怎么更换镜像源

要设置Docker镜像&#xff0c;您可以按照以下步骤进行&#xff1a; 1. 打开终端并登录到Docker主机上。 运行以下命令来编辑 Docker 的配置文件 "/etc/docker/daemon.json"&#xff08;如果不存在则新建&#xff09;&#xff1a; sudo nano /etc/docker/daemon.js…

Django系列之Celery异步框架+RabbitMQ使用

在Django项目中&#xff0c;如何集成使用Celery框架来完成一些异步任务以及定时任务呢&#xff1f; 1. 安装 pip install celery # celery框架 pip install django-celery-beat # celery定时任务使用 pip install django-celery-results # celery存储结果使用2. Django集成…

URIBuilder与SSRF

在使用一个静态扫描工具时&#xff0c;报了一个SSRF的问题&#xff0c;经过数据流的分析&#xff0c;导致此工具报SSRF的原因是在调用URIBuilder的setPath函数时&#xff0c;参数是从请求里获取的&#xff0c;导致了数据流被污染&#xff0c;因此认为由URIBuilder构造的URL也被…

作为一个产品经理带你了解Axure的安装和基本使用

1.Axure的简介 Axure是一种强大的原型设计工具&#xff0c;它允许用户创建交互式的、高保真度的原型&#xff0c;以及进行用户体验设计和界面设计。Axure可以帮助设计师和产品经理快速创建和共享原型&#xff0c;以便团队成员之间进行沟通和反馈。Axure提供了丰富的交互组件和功…

【EI会议征稿中|JPCS出版】第三届电子与集成电路技术国际学术会议(EICT 2024)

第三届电子与集成电路技术国际学术会议&#xff08;EICT 2024&#xff09; 2024 3rd International Conference on Electronics and Integrated Circuit Technology 第三届电子与集成电路技术国际学术会议&#xff08;EICT 2024&#xff09;将于2024年4月12至14日在南昌市举行…

Vue3封装一个轮播图组件

先看效果 编写组件代码 CarouselChart.vue <template><div classimg-box><el-button clickpreviousImages v-ifprops.showBtn>←</el-button><div classimg><div styledisplay: flex;gap: 20px idmove><imgclassimg-item v-for(item…

Github上火爆的个人知识管理AI大脑:Quivr

Github上火爆的个人知识管理AI大脑&#xff1a;Quivr。 演示视频&#xff1a; Github上火爆的个人知识管理AI大脑&#xff1a;Quivr 点击上面视频观看&#xff01;&#xff01;&#xff01; II. Quivr 的强大功能 与文件和应用程序聊天 把你的文件和应用看成你的对话伙伴&…
最新文章