https://github.com/hyperic/sigar

https://www.cnblogs.com/yoyotl/p/10809792.html

http://blog.sina.com.cn/s/blog_62c89b450100qerm.html

https://blog.csdn.net/a123demi/article/details/50689265

https://blog.csdn.net/weixin_42639633/article/details/116556543

https://blog.csdn.net/weixin_39950057/article/details/114206515

sigar 函数

https://www.cnblogs.com/1521299249study/p/11174162.html

https://github.com/ilyaServ/server

git clone https://github.com/ilyaServ/server.git

https://github.com/ilyaServ/server/blob/73031e040a51e8467e1d1d708fa6df87ec068421/kbe/src/lib/helper/sys_info.cpp

https://github.com/vonfking/stock/blob/ca39fde521aa124efda7fcf3a6b188134dfa374b/c2/sigar/programs/sigar_port.c

 



using namespace std;

int main(int argc, char** argv)

{
    sigar_t* sigar_cpu;

    sigar_open(&sigar_cpu);

    /*Get cpu list info,such as number...*/

    sigar_cpu_list_t cpu_list;

    int status = sigar_cpu_list_get(sigar_cpu, &cpu_list);

    if (status != SIGAR_OK)
        cout << "err" <<endl;

        int CpuNumber = cpu_list.number;

    /*Get cpu used rate,idle rate...*/

    sigar_cpu_t cpu_old;

    sigar_cpu_t cpu_current;

    sigar_cpu_get(sigar_cpu, &cpu_old);

    sigar_cpu_perc_t perc;

    //sleep(1);

    sigar_cpu_get(sigar_cpu, &cpu_current);

    sigar_cpu_perc_calculate(&cpu_old, &cpu_current, &perc);
    //cpu总使用率
    double CpuTotalUsedRate = perc.combined;

    double CpuIdleRate = perc.idle;

    cpu_old = cpu_current;

    //cout <

        sigar_cpu_list_destroy(sigar_cpu, &cpu_list);

    sigar_close(sigar_cpu);

    return 0;

}
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2011 Couchbase, Inc.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sigar.h>

#ifdef _WIN32
#include <io.h>
#include <fcntl.h>
#endif

#define DEFAULT(value, def) ((value) == SIGAR_FIELD_NOTIMPL ? (def) : (value))

#define NUM_INTERESTING_PROCS 10
#define PROC_NAME_LEN 12

struct proc {
    sigar_pid_t pid;
    sigar_uint64_t start_time;
    char name[PROC_NAME_LEN];
};

struct proc_stats {
    char name[PROC_NAME_LEN];
    uint32_t cpu_utilization;

    uint64_t pid;

    uint64_t mem_size;
    uint64_t mem_resident;
    uint64_t mem_share;
    uint64_t minor_faults;
    uint64_t major_faults;
    uint64_t page_faults;
};

struct system_stats {
    uint32_t version;
    uint32_t struct_size;

    uint64_t cpu_total_ms;
    uint64_t cpu_idle_ms;

    uint64_t swap_total;
    uint64_t swap_used;
    uint64_t swap_page_in;
    uint64_t swap_page_out;

    uint64_t mem_total;
    uint64_t mem_used;
    uint64_t mem_actual_used;
    uint64_t mem_actual_free;

    struct proc_stats interesting_procs[NUM_INTERESTING_PROCS];
};

static int find_interesting_procs(sigar_t *sigar, sigar_pid_t parent,
                                  struct proc procs[NUM_INTERESTING_PROCS])
{
    unsigned long i;
    int found = 0;

    sigar_proc_list_t proc_list;
    sigar_proc_state_t proc_state;
    sigar_proc_cpu_t proc_cpu;
    sigar_pid_t pid;

    sigar_proc_list_get(sigar, &proc_list);

    for (i = 0; i < proc_list.number; ++i) {
        pid = proc_list.data[i];

        if (sigar_proc_state_get(sigar, pid, &proc_state) != SIGAR_OK) {
            continue;
        }

        if (proc_state.ppid == parent &&
            strcmp(proc_state.name, "moxi") != 0) {

            procs[found].pid = pid;
            strncpy(procs[found].name, proc_state.name, PROC_NAME_LEN);

            if (sigar_proc_cpu_get(sigar, pid, &proc_cpu) != SIGAR_OK) {
                continue;
            }

            procs[found].start_time = proc_cpu.start_time;
            ++found;

            if (found == NUM_INTERESTING_PROCS) {
                break;
            }
        }
    }

    sigar_proc_list_destroy(sigar, &proc_list);

    return found;
}

static int populate_interesting_procs(sigar_t *sigar,
                                      struct proc *procs, int procs_count,
                                      struct system_stats *reply)
{
    int i;
    int stale = 0;

    sigar_proc_mem_t proc_mem;
    sigar_proc_cpu_t proc_cpu;

    struct proc_stats *child;

    for (i = 0; i < procs_count; ++i) {
        if (sigar_proc_mem_get(sigar, procs[i].pid, &proc_mem) != SIGAR_OK ||
            sigar_proc_cpu_get(sigar, procs[i].pid, &proc_cpu) != SIGAR_OK ||
            procs[i].start_time != proc_cpu.start_time)
        {
            stale = 1;
            continue;
        }

        child = &reply->interesting_procs[i];

        child->pid = procs[i].pid;
        strncpy(child->name, procs[i].name, PROC_NAME_LEN);
        child->cpu_utilization = DEFAULT((uint32_t) (100 * proc_cpu.percent), 0);
        child->mem_size = DEFAULT(proc_mem.size, 0);
        child->mem_resident = DEFAULT(proc_mem.resident, 0);
        child->mem_share = DEFAULT(proc_mem.share, 0);
        child->minor_faults = DEFAULT(proc_mem.minor_faults, 0);
        child->major_faults = DEFAULT(proc_mem.major_faults, 0);
        child->page_faults = DEFAULT(proc_mem.page_faults, 0);
    }

    return stale;
}

int main(void)
{
    sigar_t *sigar;
    sigar_mem_t mem;
    sigar_swap_t swap;
    sigar_cpu_t cpu;
    struct system_stats reply;

    sigar_pid_t pid;
    sigar_proc_state_t state;

    sigar_pid_t child_vm_pid;
    sigar_pid_t babysitter_pid;

    int procs_stale = 1;
    int procs_count;
    struct proc procs[NUM_INTERESTING_PROCS];

    sigar_open(&sigar);

    pid = sigar_pid_get(sigar);
    sigar_proc_state_get(sigar, pid, &state);
    child_vm_pid = state.ppid;

    sigar_proc_state_get(sigar, child_vm_pid, &state);
    babysitter_pid = state.ppid;

#ifdef _WIN32
    _setmode(1, _O_BINARY);
    _setmode(0, _O_BINARY);
#endif

    while (!feof(stdin)) {
        int req;
        int rv = fread(&req, sizeof(req), 1, stdin);
        if (rv < 1) {
            continue;
        }
        if (req != 0) {
            break;
        }
        memset(&reply, 0, sizeof(reply));
        reply.version = 2;
        reply.struct_size = sizeof(reply);

        sigar_mem_get(sigar, &mem);
        sigar_swap_get(sigar, &swap);
        sigar_cpu_get(sigar, &cpu);

        reply.cpu_total_ms = cpu.total;
        reply.cpu_idle_ms = cpu.idle + cpu.wait;

        reply.swap_total = swap.total;
        reply.swap_used = swap.used;
        reply.swap_page_in = swap.page_in;
        reply.swap_page_out = swap.page_out;

        reply.mem_total = mem.total;
        reply.mem_used = mem.used;
        reply.mem_actual_used = mem.actual_used;
        reply.mem_actual_free = mem.actual_free;

        if (procs_stale) {
            procs_count = find_interesting_procs(sigar, babysitter_pid, procs);
        }

        procs_stale = populate_interesting_procs(sigar, procs, procs_count, &reply);

        if (procs_count != NUM_INTERESTING_PROCS) {
            procs_stale = 1;
        }

        fwrite(&reply, sizeof(reply), 1, stdout);
        fflush(stdout);
    }

    return 0;
}

 

/*
This source file is part of KBEngine
For the latest info, see http://www.kbengine.org/
Copyright (c) 2008-2016 KBEngine.
KBEngine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
KBEngine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public License
along with KBEngine.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "sys_info.h"

extern "C"
{
#include "sigar.h"
#include "sigar_format.h"
}

#ifndef CODE_INLINE
#include "sys_info.inl"
#endif

namespace KBEngine
{
KBE_SINGLETON_INIT(SystemInfo);

SystemInfo g_SystemInfo;

sigar_t *_g_sigarproclist = NULL;
sigar_proc_list_t _g_proclist;
sigar_t *_g_sigar_cpu = NULL;
sigar_cpu_t _g_old_cpu;

//-------------------------------------------------------------------------------------
bool hasPID(int pid, sigar_proc_list_t* proclist)
{
	for (size_t i = 0; i < proclist->number; i++)
	{
		sigar_pid_t cpid = proclist->data[i];
		if (cpid == pid)
		{
			sigar_proc_state_t procstate;
			if (sigar_proc_state_get(_g_sigarproclist, pid, &procstate) != SIGAR_OK)
			{
				return false;
			}

			return true;
		}
	}

	return false;
}

//-------------------------------------------------------------------------------------
SystemInfo::SystemInfo()
{
	totalmem_ = 0;

	// 不要在初始化中做这件事情,因为全局静态变量这里可能在main之前被调用一次
	//_autocreate();
	//getCPUPer();
	//getProcessInfo();
}

//-------------------------------------------------------------------------------------
SystemInfo::~SystemInfo()
{
	clear();
}

//-------------------------------------------------------------------------------------
void SystemInfo::clear()
{
	if(_g_sigarproclist)
	{
		sigar_proc_list_destroy(_g_sigarproclist, &_g_proclist);
		sigar_close(_g_sigarproclist);
		_g_sigarproclist = NULL;
	}

	if(_g_sigar_cpu)
	{
		sigar_close(_g_sigar_cpu);
		_g_sigar_cpu = NULL;
	}
}

//-------------------------------------------------------------------------------------
bool SystemInfo::_autocreate()
{
	if(_g_sigarproclist == NULL)
	{
		sigar_open(&_g_sigarproclist);

		int status = sigar_proc_list_get(_g_sigarproclist, &_g_proclist);
		if (status != SIGAR_OK) 
		{
			DEBUG_MSG(fmt::format("SystemInfo::autocreate: error: {} ({}) sigar_proc_list_get\n",
					   status, sigar_strerror(_g_sigarproclist, status)));

			sigar_close(_g_sigarproclist);
			_g_sigarproclist = NULL;
			return false;
		}
	}

	return true;
}

//-------------------------------------------------------------------------------------
bool SystemInfo::hasProcess(uint32 pid)
{
    if(!_autocreate())
		return false;

	return hasPID(pid, &_g_proclist);
}

//-------------------------------------------------------------------------------------
void SystemInfo::update()
{
    if(!_autocreate())
		return;
}

//-------------------------------------------------------------------------------------
uint32 SystemInfo::countCPU()
{
	static uint32 count = 0;

	if(count == 0)
	{
		int status = SIGAR_OK;
		sigar_t *sigarcpulist;
		sigar_cpu_list_t cpulist;
		sigar_open(&sigarcpulist);
		status = sigar_cpu_list_get(sigarcpulist, &cpulist);
		
		if (status != SIGAR_OK) 
		{
			DEBUG_MSG(fmt::format("error: {} ({}) cpu_list_get\n",
				   status, sigar_strerror(sigarcpulist, status)));

			count = 1;
		}
		else
		{
			count = cpulist.number;
			sigar_cpu_list_destroy(sigarcpulist, &cpulist);
		}

		sigar_close(sigarcpulist);
	}

	return count;
}

//-------------------------------------------------------------------------------------
SystemInfo::PROCESS_INFOS SystemInfo::getProcessInfo(uint32 pid)
{
	PROCESS_INFOS infos;
	infos.cpu = 0.f;
	infos.memused = 0;
	infos.error = false;
	
	bool tryed = false;

    if(!_autocreate())
		goto _END;

_TRYGET:
	if(!hasPID(pid, &_g_proclist))
	{
		//DEBUG_MSG(fmt::format("SystemInfo::getProcessInfo: error: not found pid({})\n", pid));
		
		if(!tryed)
		{
			clear();

			tryed = true;
			infos.error = true;

			//DEBUG_MSG(fmt::format("SystemInfo::getProcessInfo: try to find the pid({})\n", pid));

			if(_autocreate())
				goto _TRYGET;
		}

		goto _END;
	}
	else
	{
		if (tryed)
		{
			//DEBUG_MSG(fmt::format("SystemInfo::getProcessInfo: found pid({})\n", pid));
		}

		infos.error = false;
	}

	infos.cpu = getCPUPerByPID(pid);
	infos.memused = getMemUsedByPID(pid);

_END:
	return infos;
}

//-------------------------------------------------------------------------------------
float SystemInfo::getCPUPer()
{
	sigar_cpu_t current;
	 
	if(_g_sigar_cpu == NULL)
		sigar_open(&_g_sigar_cpu);

	// sigar_cpu_get(_g_sigar_cpu, &_g_old_cpu);
	 
	sigar_cpu_perc_t perc;

	// while(1)
	{
		sigar_cpu_get(_g_sigar_cpu, &current);
		sigar_cpu_perc_calculate(&_g_old_cpu, &current, &perc);
	 
		// std::cout << "CPU " << perc.combined * 100 << "%\n";
		_g_old_cpu = current;
	//	sleep(1000);
	}
	 
	 
	float ret = float(perc.combined) * 100.f;
	//sigar_close(sigar_cpu);
	// DEBUG_MSG(fmt::format("SystemInfo::getCPUPer(): {}\n", ret));
	return ret;
}

//-------------------------------------------------------------------------------------
float SystemInfo::getCPUPerByPID(uint32 pid)
{
	if(pid == 0)
	{
		pid = (uint32)getProcessPID();
	}

    float percent = 0.f;
	bool tryed = false;

_TRYGET:
	if(!hasPID(pid, &_g_proclist))
	{
		//DEBUG_MSG(fmt::format("SystemInfo::getCPUPerByPID: error: not found pid({})\n", pid));

		if(!tryed)
		{
			clear();
			tryed = true;

			if(_autocreate())
				goto _TRYGET;
		}

		return 0.f;
	}

	/*
	int status = SIGAR_OK;
	// for (size_t i = 0; i < proclist.number; i++)
    {
        sigar_proc_cpu_t cpu;
        status = sigar_proc_cpu_get(_g_sigarproclist, pid, &cpu);
		if (status != SIGAR_OK) 
		{
			DEBUG_MSG(fmt::format("error: {} ({}) proc_cpu_get({})\n",
				   status, sigar_strerror(_g_sigarproclist, status), pid));
			return 0.f;
		}
    }
	*/
  // sleep(1000);

	// for (size_t i = 0; i < proclist.number; i++)
    {
        sigar_proc_cpu_t cpu;
        int status = sigar_proc_cpu_get(_g_sigarproclist, pid, &cpu);
        if (status == SIGAR_OK)
        {
			/*
            sigar_proc_state_t procstate;
            status = sigar_proc_state_get(sigarproclist, pid, &procstate);
			if (status != SIGAR_OK) 
			{
				DEBUG_MSG(fmt::format("error: {} ({}) proc_state({})\n",
					   status, sigar_strerror(sigarproclist, status), pid));
				return 0.f;
			}
			*/
            percent = float(cpu.percent) * 100.f;

#if KBE_PLATFORM == PLATFORM_WIN32
			percent /= float(countCPU());
#endif

        }
		else
		{
			DEBUG_MSG(fmt::format("error: {} ({}) proc_cpu_get({})\n",
				   status, sigar_strerror(_g_sigarproclist, status), pid));

			return 0.f;
		}
    }

	return percent;
}

//-------------------------------------------------------------------------------------
SystemInfo::MEM_INFOS SystemInfo::getMemInfos()
{
	MEM_INFOS infos;

	sigar_t *sigar;
	sigar_open(&sigar);
	sigar_mem_t sigar_mem;
	sigar_mem_get(sigar, &sigar_mem);

	infos.total = sigar_mem.total;
	infos.free = sigar_mem.actual_free;
	infos.used = sigar_mem.actual_used;

	sigar_close(sigar);
	return infos;
}

//-------------------------------------------------------------------------------------
uint64 SystemInfo::totalmem()
{
	if(totalmem_ == 0)
		totalmem_ = getMemInfos().total;

	return totalmem_;
}

//-------------------------------------------------------------------------------------
uint64 SystemInfo::getMemUsedByPID(uint32 pid)
{
	if(pid == 0)
	{
		pid = (uint32)getProcessPID();
	}

	int status;
	sigar_uint64_t total = 0;
	bool tryed = false;

_TRYGET:
	if(!hasPID(pid, &_g_proclist))
	{
		//DEBUG_MSG(fmt::format("SystemInfo::getMemUsedByPID: error: not found pid({})\n", pid));

		if(!tryed)
		{
			clear();
			tryed = true;

			if(_autocreate())
				goto _TRYGET;
		}

		return 0;
	}

    //for (i=0; i<(int)proclist.number; i++) 
	{
        sigar_proc_state_t pstate;
        sigar_proc_time_t ptime;

        status = sigar_proc_state_get(_g_sigarproclist, pid, &pstate);
        if (status != SIGAR_OK) 
		{
			DEBUG_MSG(fmt::format("error: {} ({}) proc_state({})\n",
                   status, sigar_strerror(_g_sigarproclist, status), pid));
			
			goto _END;
        }

        status = sigar_proc_time_get(_g_sigarproclist, pid, &ptime);
        if (status != SIGAR_OK) 
		{
			DEBUG_MSG(fmt::format("error: {} ({}) proc_time({})\n",
                   status, sigar_strerror(_g_sigarproclist, status), pid));

           goto _END;
        }

		sigar_proc_mem_t proc_mem;
		status = sigar_proc_mem_get(_g_sigarproclist, pid, &proc_mem);

        if (status != SIGAR_OK) 
		{
			DEBUG_MSG(fmt::format("error: {} ({}) sigar_proc_mem_get({})\n",
                   status, sigar_strerror(_g_sigarproclist, status), pid));
            
			goto _END;
        }

		total = proc_mem.resident;
    }

_END:
	return total;
}

//-------------------------------------------------------------------------------------
} 

 

 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐