muduo源码解析13-processinfo命名空间

processinfo命名空间

作用:

看不懂...  好多函数连见都没见过,这里就当是看个眼熟了,以后用得着可以过来找找看。
参考:https://blog.csdn.net/MoonWisher_liang/article/details/107332128
这个processinfo命名空间里面主要是实现了一些关于读取进程信息的函数
linux提供了一个虚拟文件系统放在/proc目录下,包含了各种用于展示内核信息的文件
允许进程通过常规I/O读取.
在/proc下保存的文件/目录是由内核在进程访问此类信息动态创建的
一个进程对应/proc下的一个子目录,就是/proc/PID
而/proc/PID下面有:fd子目录负责文件描述符,task子目录下还有子目录TID,包含线程信息

头文件:

#ifndef PROCESSINFO_H
#define PROCESSINFO_H

//#include"base/stringpiece.h"  又来?继续自己用std::string实现
#include"base/types.h"
#include"base/timestamp.h"

#include<vector>
#include<sys/types.h>

namespace mymuduo {

namespace processinfo {

pid_t pid();                //返回进程pid
string pidString();         //返回pid的字符串形式
uid_t uid();                //返回userID
string username();          //返回userID字符串
uid_t euid();               //
timestamp startTime();      //返回进程开始时间
int clockTicksPerSecond();
int pageSize();
bool isDebugBuild();

string hostname();          //主机名
string procname();
string procname(const string& stat); //自己改一下

//read /proc/self/status
string procStatus();         //进程状态
//read /proc/self/stat
string procStat();
//read /proc/self/task/stat
string threadStat();        //线程状态
//readlink /proc/self/exe
string exePath();

int openedFiles();          //进程打开的文件数目
int maxOpenFiles();         //进程最多打开的文件数目

struct CpuTime
{
    double userSeconds;
    double systemSeconds;
    CpuTime():userSeconds(0.0),systemSeconds(0.0){}
    double total() const {return userSeconds+systemSeconds;}
};

CpuTime cpuTime();          //CPU时间信息

int numThreads();           //进程中的线程数目
std::vector<pid_t> threads();   //各个线程ID

}//namespace processinfo

}//namespace mymuduo


#endif // PROCESSINFO_H

源文件:

#include "processinfo.h"

#include"base/currentthread.h"
#include"base/fileutil.h"

#include<algorithm>
#include<assert.h>
#include<dirent.h>
#include<pwd.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/resource.h>
#include<sys/times.h>

namespace mymuduo {

namespace detail {

//__thread 声明的全局变量每个线程都拥有一份,相互独立
//这里表示一个线程打开的文件数目
__thread int t_numOpenedFiles=0;

//dirent.h是POSIX.1标准定义的unix类目录操作的头文件,
//包含了许多UNIX系统服务的函数原型,例如opendir函数、readdir函数.
int fdDirFilter(const struct dirent* d)
{
    //如果dirent.d_name[0]不为空,说明有文件
    if(::isdigit(d->d_name[0]))
        ++t_numOpenedFiles;
    return 0;
}

__thread std::vector<pid_t>* t_pids=NULL;
//把每个线程的ID都存入到t_pids中
int taskDirFilter(const struct dirent* d)
{
    if (::isdigit(d->d_name[0]))
        t_pids->push_back(atoi(d->d_name));
    return 0;
}

int scanDir(const char* dirpath,int (*filter)(const struct dirent*))
{
    struct dirent** namelist=NULL;
    int result = ::scandir(dirpath,&namelist,filter,alphasort);
    assert(namelist==NULL);
    return result;
}

timestamp g_startTime = timestamp::now();
// assume those won't change during the life time of a process.
int g_clockTicks = static_cast<int>(::sysconf(_SC_CLK_TCK));
int g_pageSize = static_cast<int>(::sysconf(_SC_PAGE_SIZE));
}//namespace detail

}//namespace mymuduo


using namespace mymuduo;
using namespace mymuduo::detail;

//进程ID
pid_t processinfo::pid()
{
  return ::getpid();
}
//进程ID字符串
string processinfo::pidString()
{
  char buf[32];
  snprintf(buf, sizeof buf, "%d", pid());
  return buf;
}
//userID
uid_t processinfo::uid()
{
  return ::getuid();
}
//user名字
string processinfo::username()
{
  struct passwd pwd;
  struct passwd* result = NULL;
  char buf[8192];
  const char* name = "unknownuser";

  getpwuid_r(uid(), &pwd, buf, sizeof buf, &result);
  if (result)
  {
    name = pwd.pw_name;
  }
  return name;
}

uid_t processinfo::euid()
{
  return ::geteuid();
}
//进程启动时间
timestamp processinfo::startTime()
{
  return g_startTime;
}

int processinfo::clockTicksPerSecond()
{
  return g_clockTicks;
}

int processinfo::pageSize()
{
  return g_pageSize;
}

bool processinfo::isDebugBuild()
{
#ifdef NDEBUG
  return false;
#else
  return true;
#endif
}

string processinfo::hostname()
{
  // HOST_NAME_MAX 64
  // _POSIX_HOST_NAME_MAX 255
  char buf[256];
  if (::gethostname(buf, sizeof buf) == 0)
  {
    buf[sizeof(buf)-1] = '\0';
    return buf;
  }
  else
  {
    return "unknownhost";
  }
}

string processinfo::procname()
{
  return procname(procStat());
}

string processinfo::procname(const string& stat)
{
  string name;
  size_t lp = stat.find('(');
  size_t rp = stat.rfind(')');
  if (lp != string::npos && rp != string::npos && lp < rp)
  {
    name=std::string(stat.data()+lp+1,static_cast<int>(rp-lp-1));

  }
  return name;
}

string processinfo::procStatus()
{
  string result;
  fileutil::readFile(string("/proc/self/status"), 65536, &result);
  return result;
}

string processinfo::procStat()
{
  string result;
  fileutil::readFile(string("/proc/self/stat"), 65536, &result);
  return result;
}

string processinfo::threadStat()
{
  char buf[64];
  snprintf(buf, sizeof buf, "/proc/self/task/%d/stat", currentthread::tid());
  string result;
  fileutil::readFile(string(buf), 65536, &result);
  return result;
}

string processinfo::exePath()
{
  string result;
  char buf[1024];
  ssize_t n = ::readlink("/proc/self/exe", buf, sizeof buf);
  if (n > 0)
  {
    result.assign(buf, n);
  }
  return result;
}

int processinfo::openedFiles()
{
  t_numOpenedFiles = 0;
  scanDir("/proc/self/fd", fdDirFilter);
  return t_numOpenedFiles;
}

int processinfo::maxOpenFiles()
{
  struct rlimit rl;
  if (::getrlimit(RLIMIT_NOFILE, &rl))
  {
    return openedFiles();
  }
  else
  {
    return static_cast<int>(rl.rlim_cur);
  }
}

processinfo::CpuTime processinfo::cpuTime()
{
  processinfo::CpuTime t;
  struct tms tms;
  if (::times(&tms) >= 0)
  {
    const double hz = static_cast<double>(clockTicksPerSecond());
    t.userSeconds = static_cast<double>(tms.tms_utime) / hz;
    t.systemSeconds = static_cast<double>(tms.tms_stime) / hz;
  }
  return t;
}

int processinfo::numThreads()
{
  int result = 0;
  string status = procStatus();
  size_t pos = status.find("Threads:");
  if (pos != string::npos)
  {
    result = ::atoi(status.c_str() + pos + 8);
  }
  return result;
}

std::vector<pid_t> processinfo::threads()
{
  std::vector<pid_t> result;
  t_pids = &result;
  scanDir("/proc/self/task", taskDirFilter);
  t_pids = NULL;
  std::sort(result.begin(), result.end());
  return result;
}

测试(一些进程信息打印,测试代码跟作者的一样,没有自己改动):

#include"base/processinfo.h"
#include<iostream>

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

using namespace std;

namespace mymuduo{
namespace currentthread {
void cacheTid()
{
}
}
}


int main()
{
    printf("pid = %d\n", mymuduo::processinfo::pid());
    printf("uid = %d\n", mymuduo::processinfo::uid());
    printf("euid = %d\n", mymuduo::processinfo::euid());
    printf("start time = %s\n", mymuduo::processinfo::startTime().toFormattedString().c_str());
    printf("hostname = %s\n", mymuduo::processinfo::hostname().c_str());
    printf("opened files = %d\n", mymuduo::processinfo::openedFiles());
    printf("threads = %zd\n", mymuduo::processinfo::threads().size());
    printf("num threads = %d\n", mymuduo::processinfo::numThreads());
    printf("status = %s\n", mymuduo::processinfo::procStatus().c_str());

    std::cout<<"over...\n";
}

 

打印结果(一大堆看不懂的进程信息):

pid = 72087
uid = 1000
euid = 1000
start time = 2020年08月25日 星期2 02:24:26.1598293466
hostname = master
opened files = 4
threads = 1
num threads = 1
status = Name: mymuduo
Umask: 0002
State: R (running)
Tgid: 72087
Ngid: 0
Pid: 72087
PPid: 72086
TracerPid: 72090
Uid: 1000 1000 1000 1000
Gid: 1000 1000 1000 1000
FDSize: 64
Groups: 4 24 27 30 46 113 128 1000
NStgid: 72087
NSpid: 72087
NSpgid: 72087
NSsid: 72086
VmPeak: 15512 kB
VmSize: 15512 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 1808 kB
VmRSS: 1808 kB
RssAnon: 164 kB
RssFile: 1644 kB
RssShmem: 0 kB
VmData: 312 kB
VmStk: 132 kB
VmExe: 84 kB
VmLib: 4672 kB
VmPTE: 76 kB
VmSwap: 0 kB
HugetlbPages: 0 kB
CoreDumping: 0
Threads: 1
SigQ: 0/11386
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000200000
SigCgt: 0000000180000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
NoNewPrivs: 0
Seccomp: 0
Speculation_Store_Bypass: thread vulnerable
Cpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff
Cpus_allowed_list: 0-127
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 7
nonvoluntary_ctxt_switches: 1

over...

 

posted @ 2020-08-25 02:34  WoodInEast  阅读(231)  评论(0编辑  收藏  举报