linux c++ 根据进程名杀死一个进程

一、知识点储备

环境:centos6 , x86,g++
需求:输入参数:进程名和超时时间;功能:杀死超时的进程

  1. 杀死进程的方法:前期考虑用boost::process库以达到跨平台的目的,但是学习之后发现该库是用来管理子进程的,不能用来杀死一个不相干的进程。在linux中杀死一个进程可以使用kill(pid,SIGKILL)函数通过发送信号实现杀死进程的目的。
#include<sys/types.h>
int kill(int pid, int SIG); //第一个参数是进程的id,第二个参数是发送的信号,返回值:0--成功

2.根据进程名获得进程pid
linux系统中所有正在运行的进程都会在/proc/路径下拥有一个以自身pid命名的文件夹,文件夹中存储了该进程相关的一些信息,其中:
exe:是该进程所运行的程序的软连接;
cmd:是该程序所在的目录
status文件(/proc/***pid***/status):文件中第一行标明了该进程对应的进程名。
所以可以通过遍历/proc/下所有文件夹中的status的方式获取到该进程名对应的所有进程pid
(所谓的进程名就是执行的程序的名字,一个程序可以同时有多个进程去运行,所以一个名字可能对应多个进程pid)

3. 获取进程的运行时长
目前我查到的信息来看,没找到一个封装好的c++函数可以让我们方便得得到一个进程得运行时长,linux中普遍是通过ps命令来获取到进程的开始时间和运行时长。所以在c++中通过代码来启动命令行来得到结果并将获取到的时间变成总秒数

//将此命令中的pname和pid分别替换成自己的进程名和进程pid即可
//得到的就是一个"日-时:分:秒"结构的运行时长
ps -eo pid,etime,cmd | grep [pname] | grep [pid] | awk '{print $2}'

二、以下是各部分的实现代码

1.获取进程pid

//获取进程pid
vector<string> ProcessKiller::getPidFromName(std::string ProcessName){
    
    
    vector<string> pids;
    const char* cprocessName=ProcessName.c_str();
    DIR *dir;
    struct dirent *ptr;
    FILE *fp;
    char filepath[50];//存放cmline文件路径
    char cur_task_name[50];//存放命令行文本
    char buf[BUF_SIZE];
    dir = opendir("/proc"); //打开路径,读取下面每一个文件夹
    if (NULL != dir)
    {
    
    
        while ((ptr = readdir(dir)) != NULL) 
        {
    
    
            //如果是"."或者".."就跳过
            if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0))
                continue;
            if(DT_DIR!=ptr->d_type)
                continue;
            sprintf(filepath,"/proc/%s/status",ptr->d_name); 
            fp = fopen(filepath, "r");//打开status文件
            if (NULL != fp)
            {
    
    
                if( fgets(buf, BUF_SIZE-1, fp)== NULL ){
    
    
                fclose(fp);
                continue;
                }
                sscanf(buf,"%*s %s",cur_task_name);

                //status中的进程名与要杀死的进程名是否匹配
                if(!strcmp(cprocessName,cur_task_name)){
    
    
                   printf("PID:  %s\n",ptr->d_name);
                   pids.push_back(ptr->d_name);
                }
                fclose(fp);
            }

        }

        vector<string>::iterator it;
        std::cout<<cprocessName<<" --pids:   ";
        for(it=pids.begin();it!=pids.end();it++){
    
    
          std::cout<<*it<<"   ";
        }
        std::cout<<std::endl;
        closedir(dir);
    }
    return pids;

}

2.获取进程的运行时长(秒数)

这一段代码较长,放到下一篇了
获取进程运行时长

3.杀死进程

void ProcessKiller::killProcess(vector<string> pids,vector<string> &pids_failed){
    
    

    vector<string>::iterator it;
    for(it=pids.begin();it!=pids.end();it++){
    
    
            std::cout<<*it<<"   ";
        int num;
        sscanf((*it).c_str(), "%d", &num);
        long runtime=get_process_runtime(num, m_processName.c_str());       //get pid's running time;
        if(runtime>m_timeout){
    
    

            if(isRunning(num)==0){
    
    
                printf("%d is running,start to kill it\n",num);
                int retval = kill(num, SIGKILL);  //发送SIGKILL信号给进程,要求其停止运行
                if (retval<0)   //判断是否发生信号
                {
    
    
                   printf("kill %d failed",num);
                   pids_failed.push_back(*it);
                }
               else
                {
    
    
                   printf("%d killed\n", num);
                }
            }

        }else{
    
    
          printf("œø³Ì[ %d ]runtime<timeout, this is no need to kill it\n ",num);
        }
    }
}

4.判断进程是否在运行

// 0 : running, -1 : exit, -2 : zombie(僵尸进程)
    int ProcessKiller::isRunning(int pid)
    {
    
    
        if (0 == kill(pid, 0))
        {
    
    
            std::string path = std::string("/proc/") + std::to_string(pid) + "/status";
            std::ifstream fs;
            fs.open(path);
            if (!fs)
                return -1;

            std::string line;
            while (getline(fs, line))
            {
    
    
                std::size_t found = line.find("State:");
                if (found == std::string::npos)
                    continue;
                else
                {
    
    
                    found = line.find("zombie");
                    if (found == std::string::npos)
                        return 0;
                    else
                        return -2; // zombie
                }
            }
        }
        else
            return -1;
    }

猜你喜欢

转载自blog.csdn.net/qq_41104439/article/details/131768346