Linux C 프로그램에서 pthread의 스레드 ID를 얻는 방법은 무엇입니까?


89

Linux C 프로그램에서 pthread 라이브러리에서 만든 스레드의 스레드 ID를 인쇄하는 방법은 무엇입니까?
예를 들어 : 우리는 다음과 같은 방법으로 프로세스의 PID를 얻을 수 있습니다.getpid()

답변:


80

pthread_self() 함수는 현재 스레드의 스레드 ID를 제공합니다.

pthread_t pthread_self(void);

pthread_self()함수는 호출 스레드의 Pthread 핸들을 반환합니다. pthread_self () 함수는 호출 스레드의 정수 스레드를 리턴하지 않습니다. pthread_getthreadid_np()스레드의 정수 식별자를 반환 하려면을 사용해야 합니다.

노트:

pthread_id_np_t   tid;
tid = pthread_getthreadid_np();

이러한 호출보다 훨씬 빠르지 만 동일한 동작을 제공합니다.

pthread_id_np_t   tid;
pthread_t         self;
self = pthread_self();
pthread_getunique_np(&self, &tid);

37
원래 질문은 Linux에 관한 것이 었습니다. Linux에는 _np 함수가 포함되어 있지 않습니다. (내가보다 더 확인하지 않았다, 맨 페이지가 포함되어 있지 않습니다.)
무역 아이디어 필립에게

pthread_threadid_np는 OS X> = 10.6 및 iOS> = 3.2에서 사용할 수 있습니다.
bleater

캔 @Bleater 당신은 공식 문서를 제공하시기 바랍니다 pthread_threadid_np. 프로젝트에 사용해야하므로 iOS 및 OSX 플랫폼에서 해당 API의 안정성을 확인해야합니다. opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.h 에서 링크를 참조 했지만 올바른 것인지 확실하지 않습니다.
Vivek Maran 2015

@Vivek 공식 문서에 대한 링크가 없습니다. 링크 한 헤더와 opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.c
bleater

9
@ Trade-IdeasPhilip-명확하게 _np말하면 휴대 불가능 함을 의미합니다. Linux에는 자체적 _np인 기능이 있지만 Apple의 pthread_getthreadid_np.
Josh Kelley

80

뭐? 그 사람은 Linux 특정 및 getpid ()와 동등한 것을 요청했습니다. BSD 나 Apple이 아닙니다. 대답은 gettid ()이며 정수 유형을 반환합니다. 다음과 같이 syscall ()을 사용하여 호출해야합니다.

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

 ....

 pid_t x = syscall(__NR_gettid);

이것은 리눅스가 아닌 시스템에 이식 할 수 없지만 threadid는 직접 비교할 수 있고 획득하기 매우 빠릅니다. 일반 정수처럼 인쇄 할 수 있습니다 (예 : LOG).


9
이것은 정답이어야합니다
Matthew S

그 사람은 Linux에서 작동하는 것에 대해 물었습니다. 휴대용 방식으로 수행하는 것이 선호하는 방법으로 보입니다. 휴대가 아무것도 포함되지 않는 경우 나는 리눅스 정말 새로운 Windows ...되고 추측
재스퍼 Siepkes

2
@Jasper Siepkes 요점이 누락되었습니다. 그는 스레드에 대한 getpid ()와 동등한 LINUX 호출을 요청했습니다. 그것은 gettid ()입니다. 이 질문은 이식성이나 POSIX에 대해 묻지 않았습니다. 너무 많은 사람들이 질문을하는 것보다 과시하고 시도하고 가르치기를 원합니다. pthread_self ()는 커널 스레드 ID를 반환하지 않으며 쉽게 인쇄 할 수있는 방식으로 조작 할 수 없습니다. 또한 pthread_self는 포인터 일 가능성이 높으며 조작해서는 안되며 pthread_equal () 과만 비교됩니다. 인쇄 할 수있는 ID를 묻는 질문이 바로 gettid ()입니다.
Evan Langlois

3
@EvanLanglois 그는 pthread 라이브러리, 말 그대로 POSIX 스레드 라이브러리로 작업하고 있습니다. POSIX 호환 답변을 만드는 것은 이상하지 않습니다. "그는 스레드에 대한 getpid ()와 동등한 LINUX 호출을 요청했습니다." 아니요, getpid()예입니다. 의미론이 어려운 사양이라고 말하지 않았습니다. 사람들이 POSIX 호환 방식으로 일을한다는 것을 인식하게하여 Linux 이외의 다른 커뮤니티 (FreeBSD, Illumos, OS X 등)가 혜택을받을 수 있도록하는 것은 "과시"하지 않습니다. 내가 말했듯이 Linux가 정말로 차세대 Windows가 된 것 같습니다.
Jasper Siepkes

14

다른 답변에서 언급했듯이 pthreads는 통합 스레드 ID를 검색하는 플랫폼 독립적 인 방법을 정의하지 않습니다.

Linux 시스템에서는 다음과 같이 스레드 ID를 얻을 수 있습니다.

#include <sys/types.h>
pid_t tid = gettid();

많은 BSD 기반 플랫폼에서이 답변 https://stackoverflow.com/a/21206357/316487 은 이식 불가능한 방법을 제공합니다.

그러나 스레드 ID가 필요하다고 생각하는 이유가 제어하는 ​​다른 스레드와 동일한 스레드에서 실행 중인지 또는 다른 스레드에서 실행 중인지 알기 위해서라면이 방법에서 몇 가지 유틸리티를 찾을 수 있습니다.

static pthread_t threadA;

// On thread A...
threadA = pthread_self();

// On thread B...
pthread_t threadB = pthread_self();
if (pthread_equal(threadA, threadB)) printf("Thread B is same as thread A.\n");
else printf("Thread B is NOT same as thread A.\n");

메인 스레드에 있는지 알아야하는 경우이 질문에 대한 답변에 문서화 된 추가 방법이 있습니다. pthread_self가 프로세스의 메인 (첫 번째) 스레드인지 어떻게 알 수 있습니까? .


12
pid_t tid = syscall(SYS_gettid);

Linux는 스레드의 ID를 얻을 수 있도록 이러한 시스템 호출을 제공합니다.


9

당신이 사용할 수있는 pthread_self()

부모 pthread_create()는가 성공적으로 실행 된 후 스레드 ID를 알게 되지만 스레드를 실행하는 동안 스레드 ID에 액세스하려면 함수를 사용해야합니다 pthread_self().


7

이 한 줄은 pid, 각 threadid 및 spid를 제공합니다.

 printf("before calling pthread_create getpid: %d getpthread_self: %lu tid:%lu\n",getpid(), pthread_self(), syscall(SYS_gettid));

3

pthread_getthreadid_np내 Mac OS x에 없었습니다. pthread_t불투명 한 유형입니다. 머리를 치지 마십시오. 그것을 할당하고 void*좋다고 부르십시오. 당신이해야하는 경우 printf사용합니다 %p.


1
예, 작동합니다. 내가 필요한 것은 디버깅을 위해 인쇄하는 것이므로 0x23423423423abcdef는 tid = 1234만큼 유용합니다. 감사합니다!
Qi Fan

3

질문이 명확하지 않을뿐만 아니라 대부분의 사람들도 그 차이를 인식하지 못한다고 생각합니다. 다음 속담을 살펴보십시오.

POSIX 스레드 ID는 Linux 특정 gettid()시스템 호출 에서 반환 된 스레드 ID와 동일하지 않습니다 . POSIX 스레드 ID는 스레딩 구현에 의해 할당되고 유지됩니다. 에서 반환 된 스레드 ID gettid()는 커널에서 할당 한 번호 (프로세스 ID와 유사)입니다. 각 POSIX 스레드에는 Linux NPTL 스레딩 구현에서 고유 한 커널 스레드 ID가 있지만 일반적으로 응용 프로그램은 커널 ID에 대해 알 필요가 없습니다 (알고있는 경우 이식 할 수 없음).

발췌 : Linux 프로그래밍 인터페이스 : Linux 및 UNIX 시스템 프로그래밍 핸드북, Michael Kerrisk

IMHO, 예 1,2,3... 를 들어 스레드별로 오름차순으로 숫자를 보유하는 변수를 정의하는 구조를 전달하는 이식 가능한 방법은 하나뿐입니다 . 이렇게하면 스레드의 ID를 추적 할 수 있습니다. 그럼에도 불구하고 int pthread_equal(tid1, tid2)기능을 사용해야합니다.

if (pthread_equal(tid1, tid2)) printf("Thread 2 is same as thread 1.\n");
else printf("Thread 2 is NOT same as thread 1.\n");

(가) gettid()실제로 좋은 제안입니다, 감사합니다! 그러나 Sergey L.의 답변을 따라야했습니다. stackoverflow.com/a/21280941/2430526
SRG

1

스레드 ID를 얻는 또 다른 방법이 있습니다. 스레드를 만드는 동안

int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg);

함수 호출; 첫 번째 매개 변수 pthread_t * thread는 실제로 스레드 ID (bits / pthreadtypes.h에 정의 된 부호없는 long int)입니다. 또한 마지막 인수 void *argvoid * (*start_routine)스레드 될 함수에 전달되는 인수입니다 .

여러 인수를 전달하고 구조에 대한 포인터를 보내는 구조를 만들 수 있습니다.

typedef struct thread_info {
    pthread_t thread;
    //...
} thread_info;
//...
tinfo = malloc(sizeof(thread_info) * NUMBER_OF_THREADS);
//...
pthread_create (&tinfo[i].thread, NULL, handler, (void*)&tinfo[i]);
//...
void *handler(void *targs) {
    thread_info *tinfo = targs;
    // here you get the thread id with tinfo->thread
}

-1

이 방식으로도 쓸 수 있으며 동일한 작업을 수행합니다. 예 :

for(int i=0;i < total; i++)
{
    pthread_join(pth[i],NULL);
    cout << "SUM of thread id " << pth[i] << " is " << args[i].sum << endl;
}

이 프로그램은 pthread_t의 배열을 설정하고 각각의 합계를 계산합니다. 따라서 스레드 ID로 각 스레드의 합계를 인쇄합니다.


질문에 대한 답이 아니고 코드에 대한 설명조차 잘못되었습니다!
U. Windl

-2

플랫폼 독립적 인 방법 (c ++ 11부터 시작)은 다음과 같습니다.

#include <thread>

std::this_thread::get_id();

이것은 아마도 당신이 생각하는 것처럼 "플랫폼 독립적"이 아닙니다. 내 구현에서 pthread_t. 포인터가 될 Mac에서는 정수이고 Linux에서는 정수입니다. 또한 top예를 들어 볼 수있는 "네이티브"ID를 반영하지 않습니다 . 알아야 할 것이지만 일부 용도로는 괜찮을 수도 있습니다.
Brad Allred

1
C11 (C에 관한 질문)에서는 threads.h에서 thrd_current ()를 사용합니다.
jerry
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.