티스토리 뷰

개발/그 외 개발관련

syscall(__NR_getpid)와 syscall(__NR_gettid)

부캐: 개발하는 조대리 2024. 11. 15. 09:03
반응형

syscall(__NR_getpid)와 syscall(__NR_gettid)

syscall(__NR_getpid)와 syscall(__NR_gettid)는 각각 프로세스 ID스레드 ID를 얻기 위한 시스템 호출입니다. 이 두 호출의 차이점은 주로 프로세스와 스레드의 ID를 다루는 방식에 있습니다. 안드로이드와 리눅스 같은 유닉스 기반 시스템에서는 이 둘을 구별해서 사용해야 하는 상황이 자주 발생합니다. 아래에서 이 둘의 차이와 각각의 목적에 대해 설명하겠습니다.

 

 

 

 syscall(__NR_getpid)

  • getpid() 시스템 호출은 현재 실행 중인 프로세스의 ID (Process ID, PID)를 반환합니다.
  • 프로세스는 독립된 실행 단위이며, 여러 스레드가 한 프로세스 내에서 실행됩니다.
  • 모든 스레드는 동일한 프로세스 ID를 공유합니다. 즉, 한 프로세스 내의 스레드들이 호출한 getpid()는 항상 동일한 PID를 반환합니다.
  • 이를 통해 프로세스 전체를 식별하는 ID를 얻을 수 있습니다.

사용 예시

#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>

int main() {
    pid_t pid = syscall(__NR_getpid); // 프로세스 ID 얻기
    printf("Process ID: %d\n", pid);
    return 0;
}
  • 여기서 syscall(__NR_getpid)는 현재 실행 중인 프로세스의 ID를 반환합니다.
  • 예를 들어, 하나의 애플리케이션에서 여러 스레드가 실행 중일 경우, 모든 스레드에서 호출한 getpid()는 동일한 PID를 반환합니다.

 

 

 

 syscall(__NR_gettid)

  • gettid() 시스템 호출은 현재 실행 중인 스레드의 ID (Thread ID, TID)를 반환합니다.
  • 리눅스와 안드로이드에서 스레드는 Lightweight Process (LWP)로 관리되며, 각 스레드는 고유한 스레드 ID (TID)를 가집니다.
  • 각 스레드는 프로세스 ID와 달리 고유한 TID를 가지므로, gettid()를 사용하면 각 스레드를 구분할 수 있습니다.
  • TID는 특정 스레드에만 해당되는 고유한 ID로, 이를 통해 스레드 간의 동작을 제어하거나 추적할 수 있습니다.

사용 예시

#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>

int main() {
    pid_t tid = syscall(__NR_gettid); // 스레드 ID 얻기
    printf("Thread ID: %d\n", tid);
    return 0;
}
  • 여기서 syscall(__NR_gettid)는 현재 스레드의 ID를 반환합니다.
  • 멀티스레드 애플리케이션의 경우, 각 스레드는 서로 다른 TID를 가지므로, 이를 사용하면 특정 스레드를 식별할 수 있습니다.

 

 

 

 프로세스와 스레드 ID의 차이

  • getpid(): 프로세스의 ID를 반환하며, 모든 스레드는 동일한 PID를 공유합니다.
  • gettid(): 스레드의 ID를 반환하며, 각 스레드는 고유한 TID를 가집니다. 이 TID는 리눅스에서 스레드 자체를 구분하는 데 사용됩니다.

프로세스는 독립된 실행 단위로, 메모리 공간을 독립적으로 가지고 있습니다. 반면, 스레드는 동일한 프로세스 내에서 실행되는 여러 작업 단위로, 메모리 공간을 서로 공유하지만 독립적인 실행 흐름을 가집니다. 이러한 차이 때문에, 여러 스레드의 ID를 정확하게 추적하고 제어하기 위해서는 TID가 필요합니다.

 

 

 

 실제 활용 예시

  1. 디버깅 및 로깅:
    • gettid()를 사용하여 멀티스레드 프로그램에서 각 스레드를 식별하고 로그를 남기는 데 유용합니다. 스레드마다 고유한 ID를 기록하면, 나중에 디버깅 시 어떤 스레드에서 문제가 발생했는지 쉽게 알 수 있습니다.
  2. 시그널 전송:
    • 리눅스 시스템에서는 kill() 함수를 사용해 시그널을 보낼 때 PID를 지정하면 해당 프로세스의 모든 스레드에 시그널이 전달됩니다.
    • 반면에, TID를 이용하면 특정 스레드에만 시그널을 보낼 수 있습니다. 예를 들어, syscall(SYS_tgkill, pid, tid, SIGTERM)을 사용하면 특정 프로세스의 특정 스레드에만 시그널을 보낼 수 있습니다.
  3. 스레드 수준 작업:
    • gettid()는 특정 스레드에 대해 우선순위 설정이나 스케줄링 정책을 조절할 때 사용됩니다. 이를 통해 스레드 단위의 제어가 가능하며, 애플리케이션의 성능을 최적화할 수 있습니다.

 

 

 

 정리

  • syscall(__NR_getpid): 현재 프로세스의 프로세스 ID (PID)를 반환합니다. 모든 스레드가 동일한 PID를 공유합니다.
  • syscall(__NR_gettid): 현재 스레드의 스레드 ID (TID)를 반환합니다. 각 스레드는 고유한 TID를 가지므로, 스레드를 구분하거나 특정 스레드에만 시그널을 보내는 등 스레드 단위의 제어를 할 때 유용합니다.

 

멀티스레드 애플리케이션에서 스레드와 프로세스를 정확하게 식별하고 관리하는 것은 매우 중요하며, getpid()와 gettid()를 적절히 사용하면 디버깅, 성능 최적화, 시그널 제어 등의 작업을 쉽게 수행할 수 있습니다.

 

 


 

 

개인적으로 학습하면서 정리한 내용입니다.
잘못된 내용이 있을 경우 알려주시면 확인 후 수정 및 반영하도록 하겠습니다.

오늘도 감사합니다.(__)