프로그래밍/리눅스 프로그래밍

프로그램 중복 실행 확인 코드

jinkwon.kim 2021. 10. 11. 01:58
728x90
반응형

개발 방향

pid와 symbolic link를 사용하여 프로그램의 중복 확인을 확인 한다. 

 

개발 절차 

1. 현재 process의 process 이름과 pid와 현재 실행 절대 경로를 구함

2. ps -ef 를 통하여 prceess 이름과 동이란 process의 pid를 구함 

3. 2번에서 구한 pid를 /proc/ 및에서 찾아서 실행 파일의 경로를 찾아냄

3. 찾은 경로와 1번에서 경롸 3번에 찾은 경로를 비교하여 중복 실행을 확인 

 

코드

#include <iostream>
#include <unistd.h>
#include <limits.h>
#include <sstream>

bool CheckDuplicatiedProcess(std::string process_name) {
        FILE *fp = nullptr;
        char run_pid[64] = {0, };
        char cur_path[1024] = {0, };
        pid_t cur_pid = getpid();

        /*
         * 현재 프로세스의 전체 경로 구하기
         */
        std::string prog_name = process_name.substr(2, std::string::npos);
        std::string current_path = getcwd(cur_path, 1024);
        std::string curr_full_path = current_path + "/" + prog_name;

        /*
         * 현재 program의 명으로 실행된 프로세스 찾아내기
         */
        std::ostringstream oss;
        oss << "ps -ef | grep " << prog_name << "| grep -v grep | awk -F ' ' '{print $2}'";

        if ((fp = popen(oss.str().c_str(), "r")) != nullptr) {
                while (fgets(run_pid, 64, fp)) {
                        /*
                         * 현재 process의 pid와찾은 pid의 찾은 pid와 같은지 확인
                         */
                        if (cur_pid != atoi(run_pid)) {
                                char find_path[PATH_MAX] = {0, };
                                std::ostringstream link_path;

                                link_path << "/proc/" << atoi(run_pid) << "/exe";
                                std::cout << "link path : "  << link_path.str() << std::endl;
                                ssize_t len = ::readlink(link_path.str().c_str(), find_path, sizeof(find_path)-1);
                                if (len != -1) {
                                        find_path[len] = '\0';
                                }

                                std::cout << "current pid      : " << cur_pid << std::endl;
                                std::cout << "find pid         : " << atoi(run_pid) << std::endl;
                                std::cout << "curr_full_path   : " << curr_full_path << std::endl;
                                std::cout << "find path        : " << find_path << std::endl;

                                if (curr_full_path == find_path) {
                                        return true;
                                }
                        }
                }
        }
        return false;
}

int main(int argc, char **argv)
{
        if (true == CheckDuplicatiedProcess(argv[0])) {
                std::cout << "result : duplication "<< std::endl;
        } else {
                std::cout << "result : not dupication " << std::endl;
        }

        usleep(100 * 1000000);
        return 0;
}

 

컴파일 방법 

g++ main.cpp -std=c++11

 

실행 결과 

728x90
반응형