[C] 자신과 동일한 프로세스 이름이 가동중인지 확인하는 코드 (중복 실행 차단)

프로그래밍/C, C++|2024. 8. 27. 16:28
반응형

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>

int is_another_instance_running(const char *process_name, pid_t current_pid) {
    DIR *dir;
    struct dirent *entry;
    FILE *fp;
    char path[256], cmdline[256];

    dir = opendir("/proc");
    if (dir == NULL) {
        perror("opendir");
        return 0;
    }

    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_type == DT_DIR && atoi(entry->d_name) > 0) {
            snprintf(path, sizeof(path), "/proc/%s/cmdline", entry->d_name);
            fp = fopen(path, "r");
            if (fp != NULL) {
                if (fgets(cmdline, sizeof(cmdline), fp) != NULL) {
                    // 프로세스 이름이 같고 현재 프로세스가 아닌 경우
                    if (strstr(cmdline, process_name) != NULL && atoi(entry->d_name) != current_pid) {
                        fclose(fp);
                        closedir(dir);
                        return 1;  // 다른 인스턴스가 실행 중임
                    }
                }
                fclose(fp);
            }
        }
    }

    closedir(dir);
    return 0;  // 다른 인스턴스가 실행 중이지 않음
}

int main(int argc, char *argv[]) {
    pid_t current_pid = getpid();  // 현재 프로세스의 PID 가져오기
    const char *process_name = argv[0];  // 자신의 실행 파일 이름

    // 실행 파일 이름에서 경로 제거 (예: ./myprogram -> myprogram)
    const char *base_name = strrchr(process_name, '/');
    if (base_name) {
        base_name++;  // '/' 이후의 문자열을 사용
    } else {
        base_name = process_name;  // 경로가 없는 경우 원래 이름 사용
    }

    if (is_another_instance_running(base_name, current_pid)) {
        printf("이미 가동 중입니다. 프로그램을 종료합니다.\n");
    } else {
        printf("미가동 상태입니다. 프로그램을 시작합니다.\n");
        // 여기에 프로그램의 메인 코드를 작성
        while (1) {
            sleep(10);  // 예시로 무한 대기
        }
    }

    return 0;
}

반응형

댓글()

[C++] 파일쓰기 예제

프로그래밍/C, C++|2023. 12. 11. 17:02
반응형

#include<fstream>
#include<iostream>
#include<string>
 
using namespace std;
 
int main() {
    fstream my_file;
    my_file.open("a.txt", ios::out);    // 이 파일이 생성됩니다.
    my_file << "test" << endl;           // test 라는 내용이 들어가며
    my_file.write("12345", 5);           // 이렇게도 추가할 수 있습니다.
    my_file.close();
}

 

 

* 참고로 위 코드는 반복 실행시 계속 새로운 파일로 쓰이게 되며,

파일이 있을때 내용을 추가하고자 할경우 아래와 같이 ios::app (append) 플래그를 사용하면 됩니다.

my_file.open("a.txt", ios::out | ios::app);

 

반응형

댓글()

C/C++ 프로그레스바 (ProgressBar)

프로그래밍/C, C++|2023. 6. 16. 07:57
반응형

C/C++의 콘솔 환경에서 프로그레스바 (진행바) 구현 소스입니다.

아래와 같이 심플하게 개수, 프로그레스바, 진행률 이 출력됩니다.

 

10/10 [==================================================] 100%

 

#include <stdio.h>
#include <stdlib.h>  
#include <windows.h> // Sleep 함수 

int main() {
        const char bar = '='; // 프로그레스바 문자  
        const char blank = ' '; // 비어있는 프로그레스바 문자  
        const int LEN = 20; // 프로그레스바 길이  
        const int MAX = 1000; // 진행작업 최대값 
        const int SPEED = 50; // 카운트 증가 대기시간  
        int count = 0; // 현재 진행된 작업  
        int i; // 반복문 전용 변수  
        float tick = (float)100/LEN; // 몇 %마다 프로그레스바 추가할지 계산 
        printf("%0.2f%% 마다 bar 1개 출력\n\n", tick); 
        int bar_count; // 프로그레스바 갯수 저장 변수  
        float percent; // 퍼센트 저장 변수  
        while(count <= MAX) {
                printf("\r%d/%d [", count, MAX); // 진행 상태 출력  
                percent = (float)count/MAX*100; // 퍼센트 계산  
                bar_count = percent/tick; // 프로그레스바 갯수 계산  
                for(i=0; i<LEN; i++) { // LEN길이의 프로그레스바 출력  
                        if(bar_count > i) { // 프로그레스바 길이보다 i가 작으면 
                                printf("%c", bar);
                        } else { // i가 더 커지면  
                                printf("%c", blank);
                        }
                }
                printf("] %0.2f%%", percent); // 퍼센트 출력  
                count++; // 카운트 1증가  
                Sleep(SPEED); // SPEEDms 대기  
        }
        printf(" done!\n\n");
        system("pause"); // 프로그램 종료 전 일시정지  
        return 0; 
}

 

1000개의 전체 작업량 중 1개가 완료되었다면 진행률은 0.1%가 됩니다.
현재 진행량/전체 진행량 * 100 = 진행률(%)
100분율 계산법입니다.
해당 연산은 코드의 19행에서 진행하고 있습니다.
현재 진행량은 코드상에서 count 변수
전체 진행향은 코드상에서 MAX 변수입니다.

진행률을 계산했으면 해당 진행률을 기준으로 프로그레스바(진행바)를 출력해야합니다.
100(%)/프로그레스바 길이 = 몇 %마다 프로그레스바 1개 출력
만약 프로그레스바의 길이가 20이라고 하면
100/20 = 5
[====================] 100%
위의 모습일겁니다.

길이는 고정되어있음으로 진행률 퍼센트에 따라 = 문자를 출력해줘야 하죠
코드의 13행에서 해당 계산을 진행하고 있습니다.
계산 후 tick 이라는 변수에 저장해두었습니다.

20길이의 프로그레스바는 5% 마다 = 한개를 출력합니다.
10%라고 하면 == 를 출력하겠죠?

17~31행의 while 문은 0~전체 진행량까지 반복하는 반복문입니다.
19행에서 매번 반복마다 진행률(%)을 계산하여
20행에서 프로그레스바 = 문자를 몇개 출력할지 계산한 후
그 아래 21행 for문에서 출력을 합니다.

for문은 0~LEN 까지 반복을 하는데 LEN은 프로그레스바의 길이가 저장되있는 변수이름입니다.
20이라고 가정하면 0~20까지 반복하계되죠
bar_count는 20행에서 현재 %는 몇개의 =문자를 출력할지 저장되어있습니다.

만약 프로그레스바 길이가 20이고 진행률이 7%라고 가정합시다.

1 - 13행처럼 먼저 몇 %마다 =문자를 출력할지 계산
100/20 = 5(%)
tick = 5

2 - bar_count에 현재 퍼센트는 몇개의 =를 출력할지 계산
percent/tick = 갯수
7/5 = 1(나머지 버림)
bar_count = 1

3 - for문에서 출력
LEN이 20이므로 i = 0~20
if(bar_count > i) 
0~20까지 i가 증가하면서 bar_count와 비교하여 출력
bar_count는 현재 1이 저장되어있으므로 i가 0일때만 참
20번 반복하면서 =하나를 출력하게 되고
거짓인 경우에는 else 로 가서 공백을 출력합니다.

4 - for문으로 출력 후 퍼센트 출력 및 count 증가
count(현재 진행량)를 1 증가

위의 과정을 현재 진행량~전체 진행량까지 반복하여 100%가 되면 종료합니다.
출력하는데 왜 이어서 출력이 되지않고 원래 위치 그대로에서 출력될까요?
그 문제는 18행에 있습니다.
printf("\r")

\r 이스케이프 시퀀스는 해당 라인의 첫 번째 위치로 이동합니다.
첫 번째로 이동한 후 다시 출력을 하게되어 위치가 바뀌지않고 진행되는이유입니다.

 

[출처] https://geundung.dev/43

 

 

반응형

댓글()

[C/C++] int 를 char 또는 const char* 로 변환하기

프로그래밍/C, C++|2022. 6. 30. 13:13
반응형

숫자 뒤에 0 을 붙이면 문자로 인식합니다.

 

const int pos = 100;

const char* charpos = pos+"0";

 

반응형

댓글()

C++ 프로그램 중복 실행 방지 (윈도우 기반)

프로그래밍/C, C++|2021. 5. 18. 13:16
반응형

HANDLE Mutex;
const char ProgMutex[] = "Sysdocu"; // 프로젝트명
if ((Mutex = OpenMutex(MUTEX_ALL_ACCESS, false, ProgMutex)) == NULL)
    Mutex = CreateMutex(NULL, true, ProgMutex);
else {
    MessageBox(NULL, "이미 실행중입니다.", "알림", MB_OK);
    return 0;
}

 

 

반응형

댓글()

C++ 에서 구동 파일의 절대 경로 확인하기 (windows)

프로그래밍/C, C++|2021. 5. 17. 14:29
반응형

1. 구동 파일 절대 경로 출력 (파일)

 

char cCurrentPath[FILENAME_MAX];
GetModuleFileName(NULL, cCurrentPath, MAX_PATH);
cCurrentPath[sizeof(cCurrentPath) - 1] = '\0';
printf("The current working file is %s\n", cCurrentPath);

 

 

2. 구동 파일 절대 경로 출력 (디렉토리)

- 위 소스에서 코드 한줄만 더 추가하면 파일명이 제외된 디렉토리만 출력됩니다.

PathRemoveFileSpec(cCurrentPath);

printf("The current working directory is %s\n", cCurrentPath);

 

반응형

댓글()

(에러) 인수 1을(를) 'ATL::CString'에서 'const char *'(으)로 변환할 수 없습니다.

프로그래밍/C, C++|2021. 5. 14. 14:15
반응형

코드나 환경에 따라 아래와 같은 에러가 출력될 수 있습니다.

저는 디렉토리 이동 함수를 사용할때 메세지가 출력 되었습니다.

 

(에러)

'int _chdir(const char *)': 인수 1을(를) 'ATL::CString'에서 'const char *'(으)로 변환할 수 없습니다.

 

(해결)

이경우 아래와 같이 해주세요.

_chdir((char*)(LPCTSTR)strFolderPath);

 

 

반응형

댓글()

Windows C++ 로 시스템 DISK 사용률 출력하기

프로그래밍/C, C++|2021. 4. 22. 09:33
반응형

BOOL  fResult;

unsigned __int64 i64FreeBytesToCaller,

    i64TotalBytes,

    i64FreeBytes;

fResult = GetDiskFreeSpaceEx(L"C:",

    (PULARGE_INTEGER)&i64FreeBytesToCaller,

    (PULARGE_INTEGER)&i64TotalBytes,

    (PULARGE_INTEGER)&i64FreeBytes);

if (fResult)

{

    printf("Available space to caller = %I64u MB\n",

        i64FreeBytesToCaller / (1024 * 1024));

    printf("Total space               = %I64u MB\n",

        i64TotalBytes / (1024 * 1024));

    printf("Free space on drive       = %I64u MB\n",

        i64FreeBytes / (1024 * 1024));

}

 

[출처] https://stackoverflow.com/questions/11917946/how-do-i-get-available-disk-space-from-windows-using-c

반응형

댓글()

Windows C++ 로 시스템 메모리(MEM) 사용률 출력하기

프로그래밍/C, C++|2021. 4. 22. 09:28
반응형

 

MEMORYSTATUSEX memInfo;

memInfo.dwLength = sizeof(MEMORYSTATUSEX);

GlobalMemoryStatusEx(&memInfo);

DWORDLONG totalPhysMem = memInfo.ullTotalPhys; // 전체 메모리

DWORDLONG availPhysMem = memInfo.ullAvailPhys; // 남은 메모리

printf("MEM : %I64u %I64u\n", totalPhysMem / 1024, availPhysMem / 1024); // KB 로 출력

 

[참고] https://ospace.tistory.com/514

반응형

댓글()

Windows C++ 로 시스템 CPU 사용률 출력하기

프로그래밍/C, C++|2021. 4. 22. 08:53
반응형

#include <Windows.h>

#include <iostream>

using namespace std;

static float CalculateCPULoad();

static unsigned long long FileTimeToInt64();

float GetCPULoad();

int main()

{

    printf("%.1f", GetCPULoad()); // 소수점 1자리까지 출력

    return 0;

}

static float CalculateCPULoad(unsigned long long idleTicks, unsigned long long totalTicks)

{

    static unsigned long long _previousTotalTicks = 0;

    static unsigned long long _previousIdleTicks = 0;

    unsigned long long totalTicksSinceLastTime = totalTicks - _previousTotalTicks;

    unsigned long long idleTicksSinceLastTime = idleTicks - _previousIdleTicks;

    float ret = 1.0f - ((totalTicksSinceLastTime > 0) ? ((float)idleTicksSinceLastTime) / totalTicksSinceLastTime : 0);

    _previousTotalTicks = totalTicks;

    _previousIdleTicks = idleTicks;

    return ret;

}

static unsigned long long FileTimeToInt64(const FILETIME& ft) { return (((unsigned long long)(ft.dwHighDateTime)) << 32) | ((unsigned long long)ft.dwLowDateTime); }

// Returns 1.0f for "CPU fully pinned", 0.0f for "CPU idle", or somewhere in between

// You'll need to call this at regular intervals, since it measures the load between

// the previous call and the current one.  Returns -1.0 on error.

float GetCPULoad()

{

    FILETIME idleTime, kernelTime, userTime;

    return GetSystemTimes(&idleTime, &kernelTime, &userTime) ? CalculateCPULoad(FileTimeToInt64(idleTime), FileTimeToInt64(kernelTime) + FileTimeToInt64(userTime)) : -1.0f;

}

 

[출처] https://stackoverflow.com/questions/23143693/retrieving-cpu-load-percent-total-in-windows-with-c

 

반응형

댓글()

Visual Studio 2019 설치 (C / C++컴파일러) 및 몇가지 컴파일 에러 해결 방법

프로그래밍/C, C++|2021. 4. 19. 10:56
반응형

아래 URL 에서 Visual Studio 를 다운로드 할 수 있습니다.

https://visualstudio.microsoft.com/ko/thank-you-downloading-visual-studio/?sku=Community&rel=16

 

Installer 실행시 개발 종류에 대해 선택하는데 여기서는 'C++ 데스크톱 개발' 을 선택하고 설치하였습니다.

 

 

[ 사용해보기 - 예제 및 컴파일 ]

Visual Studio 가 설치 되면 실행을 하고 새 프로젝트 (빈 프로젝트) 를 생성합니다.

우측에 솔루션 탐색기가 있는데 그중 '소스 파일' 우클릭 후 '추가 > 새항목 > C++ 파일(.cpp)' 순서로 클릭합니다.

 

1) 예제

#include <stdio.h>

int main() {

    printf("hello world!");

    return 0;

}

 

2) 컴파일 방법

Ctrl + F5 를 누르면 컴파일이 되고, 명령프롬프트 창이 뜨면서 파일이 자동으로 실행되어집니다.

간단히 상단 메뉴중 '로컬 Windows 디버거' 버튼을 눌러도 됩니다. (64bit 실행 파일을 만들 경우 앞에 메뉴를 x64 로 선택)

 

컴파일 된 실행 파일은 아래 디렉토리에 있습니다.

C:\Users\{사용자명}\source\repos\{프로젝트명}\x64\Debug\{프로젝트명}.exe

 

 

* 참고

pthread 사용방법

https://wnsgml972.github.io/c/2018/05/07/c_windows_pthread/

 

socklen_t 코드 사용법

#include <WS2tcpip.h> 추가

 

strcpy 사용시

프로젝트 > 속성 > C/C++ (전처리기) > 전처리기 정의 에 '_CRT_SECURE_NO_WARNINGS' 추가

 

'timespec' 'struct' 에러 처리법

#define HAVE_STRUCT_TIMESPEC 추가

 

아래와 유사한 에러가 발생된 경우

에러 : LNK2019 __imp_acceptmain 함수에서 참조되는 확인할 수 없는 외부 기호

#pragma comment(lib, "ws2_32.lib") 추가

반응형

댓글()