Golang如何解析proc/[pid]/stat数据中的第14、15、16和17个值

Golang如何解析proc/[pid]/stat数据中的第14、15、16和17个值

func (p *Unixprocess) Refresh() error {
	statPath := fmt.Sprintf("/proc/%d/stat", p.pid)
	dataBytes, err := ioutil.ReadFile(statPath)
	if err != nil {
		return err
	}

	// 首先,解析出镜像名称
	data := string(dataBytes)
	binStart := strings.IndexRune(data, '(') + 1
	binEnd := strings.IndexRune(data[binStart:], ')')
	p.binary = data[binStart : binStart+binEnd]  //保存进程名称

	// 跳过镜像名称开始解析其余部分
	data = data[binStart+binEnd+2:]
	_, err = fmt.Sscanf(data,
		"%c %d %d  %d",
		&p.state,
		&p.ppid,
		&p.pgrp,
		&p.sid,
		)
	

	return err
}

更多关于Golang如何解析proc/[pid]/stat数据中的第14、15、16和17个值的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

各位。你们提出的问题本质上都是同一类问题,而且恕我直言,提问方式也有些失礼。仅仅写个标题然后贴上一大段代码是非常懒惰的提问方式,这会让大量读者承担理解问题和背景的责任,而不是由你花时间解释清楚。相反,请认真说明你的问题,提供能够重现问题的完整代码片段(建议使用play.golang.org),并附上运行所需的示例数据等。

如果你们都是同班同学并且正在学习这些内容,请互相交流讨论。询问你们的指导老师——既然他们领了薪水,就有责任进行讲解。

如果这是课程作业中要求通过互联网资源独立解决问题的部分,那么你们采取的方式是错误的——请参考上文关于正确提问的建议。

我们都很乐意提供帮助,但就我个人而言,这种情况开始让人感到有些疲惫了。


编辑:我注意到另一个话题中已经表达了基本相同的观点,而且表述得更好。总之如此。

更多关于Golang如何解析proc/[pid]/stat数据中的第14、15、16和17个值的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在解析/proc/[pid]/stat文件时,第14、15、16和17个字段分别对应进程的utime、stime、cutime和cstime。这些字段表示进程在用户模式和内核模式下的CPU时间消耗。

以下是修改后的代码,正确解析这些字段:

func (p *Unixprocess) Refresh() error {
    statPath := fmt.Sprintf("/proc/%d/stat", p.pid)
    dataBytes, err := ioutil.ReadFile(statPath)
    if err != nil {
        return err
    }

    // 解析进程名称
    data := string(dataBytes)
    binStart := strings.IndexRune(data, '(') + 1
    binEnd := strings.IndexRune(data[binStart:], ')')
    p.binary = data[binStart : binStart+binEnd]

    // 跳过进程名称,解析其余字段
    data = data[binStart+binEnd+2:]
    
    // 添加utime, stime, cutime, cstime字段到Unixprocess结构体
    _, err = fmt.Sscanf(data,
        "%c %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
        &p.state,
        &p.ppid,
        &p.pgrp,
        &p.sid,
        &p.tty_nr,
        &p.tpgid,
        &p.flags,
        &p.minflt,
        &p.cminflt,
        &p.majflt,
        &p.cmajflt,
        &p.utime,    // 第14个字段: 用户模式CPU时间
        &p.stime,    // 第15个字段: 内核模式CPU时间  
        &p.cutime,   // 第16个字段: 子进程用户模式CPU时间
        &p.cstime,   // 第17个字段: 子进程内核模式CPU时间
    )

    return err
}

确保在Unixprocess结构体中定义了相应的字段:

type Unixprocess struct {
    pid     int
    binary  string
    state   rune
    ppid    int
    pgrp    int
    sid     int
    tty_nr  int
    tpgid   int
    flags   uint
    minflt  uint
    cminflt uint
    majflt  uint
    cmajflt uint
    utime   uint  // 用户模式CPU时间 (时钟滴答数)
    stime   uint  // 内核模式CPU时间 (时钟滴答数)
    cutime  int   // 子进程用户模式CPU时间
    cstime  int   // 子进程内核模式CPU时间
}

这些时间值以时钟滴答(clock ticks)为单位,可以通过sysconf(_SC_CLK_TCK)获取每秒的时钟滴答数来转换为秒数。

回到顶部