Linux C 프로그램에서 pthread 라이브러리에서 만든 스레드의 스레드 ID를 인쇄하는 방법은 무엇입니까?
예를 들어 : 우리는 다음과 같은 방법으로 프로세스의 PID를 얻을 수 있습니다.getpid()
답변:
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);
pthread_threadid_np
. 프로젝트에 사용해야하므로 iOS 및 OSX 플랫폼에서 해당 API의 안정성을 확인해야합니다. opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.h 에서 링크를 참조 했지만 올바른 것인지 확실하지 않습니다.
_np
말하면 휴대 불가능 함을 의미합니다. Linux에는 자체적 _np
인 기능이 있지만 Apple의 pthread_getthreadid_np
.
뭐? 그 사람은 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).
getpid()
예입니다. 의미론이 어려운 사양이라고 말하지 않았습니다. 사람들이 POSIX 호환 방식으로 일을한다는 것을 인식하게하여 Linux 이외의 다른 커뮤니티 (FreeBSD, Illumos, OS X 등)가 혜택을받을 수 있도록하는 것은 "과시"하지 않습니다. 내가 말했듯이 Linux가 정말로 차세대 Windows가 된 것 같습니다.
다른 답변에서 언급했듯이 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가 프로세스의 메인 (첫 번째) 스레드인지 어떻게 알 수 있습니까? .
pthread_getthreadid_np
내 Mac OS x에 없었습니다. pthread_t
불투명 한 유형입니다. 머리를 치지 마십시오. 그것을 할당하고 void*
좋다고 부르십시오. 당신이해야하는 경우 printf
사용합니다 %p
.
질문이 명확하지 않을뿐만 아니라 대부분의 사람들도 그 차이를 인식하지 못한다고 생각합니다. 다음 속담을 살펴보십시오.
POSIX 스레드 ID는 Linux 특정
gettid()
시스템 호출 에서 반환 된 스레드 ID와 동일하지 않습니다 . POSIX 스레드 ID는 스레딩 구현에 의해 할당되고 유지됩니다. 에서 반환 된 스레드 IDgettid()
는 커널에서 할당 한 번호 (프로세스 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
스레드 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 *arg
는 void * (*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
}
플랫폼 독립적 인 방법 (c ++ 11부터 시작)은 다음과 같습니다.
#include <thread>
std::this_thread::get_id();
pthread_t
. 포인터가 될 Mac에서는 정수이고 Linux에서는 정수입니다. 또한 top
예를 들어 볼 수있는 "네이티브"ID를 반영하지 않습니다 . 알아야 할 것이지만 일부 용도로는 괜찮을 수도 있습니다.