C ++ 11에서 정수 스레드 ID를 얻는 방법
c ++ 11은 현재 스레드 ID를 가져올 수 있지만 정수 유형으로 캐스팅 할 수 없습니다.
cout<<std::this_thread::get_id()<<endl;
출력 : 139918771783456
cout<<(uint64_t)std::this_thread::get_id()<<endl;
오류 : 'std :: thread :: id'유형에서 다른 유형과 동일한 'uint64_t'유형으로의 잘못된 캐스트 : 'std :: thread :: id'유형에서 'uint32_t'유형으로의 잘못된 캐스트
정수 스레드 ID를 얻기 위해 포인터 캐스팅을 정말로 원하지 않습니다. 그것을하기위한 합리적인 방법 (휴대용이되기를 원하기 때문에 표준)이 있습니까?
이식 가능한 솔루션은 자신이 생성 한 ID를 스레드에 전달하는 것입니다.
int id = 0;
for(auto& work_item : all_work) {
std::async(std::launch::async, [id,&work_item]{ work_item(id); });
++id;
}
std::thread::id
유형은 비교에 사용되는 경우에만,하지 (즉,이 캔에 말한대로 : 산술에 대한 식별자 ). 생산에도 해당 텍스트 표현 operator<<
입니다 지정되지 않은 당신이 숫자의 표현 인에 의존하지 수 있습니다.
또한 std::thread::id
자신의 ID에 대한 값 맵을 사용 하고 ID를 직접 전달하는 대신 스레드간에 적절한 동기화를 통해이 맵을 공유 할 수 있습니다.
당신은 할 필요가 있습니다
std::hash<std::thread::id>{}(std::this_thread::get_id())
를 얻을 수 있습니다 size_t
.
에서 cppreference :
클래스 에
std::hash
대한 템플릿 전문화를std::thread::id
통해 사용자는 스레드 식별자의 해시를 얻을 수 있습니다.
또 다른 ID (아이디어? ^^)는 stringstreams를 사용하는 것입니다.
std::stringstream ss;
ss << std::this_thread::get_id();
uint64_t id = std::stoull(ss.str());
일이 잘못되는 경우 예외를 원하지 않으면 try catch를 사용하십시오.
한 가지 아이디어는 스레드 로컬 저장소를 사용하여 변수를 저장하는 것입니다.-스레드 로컬 저장소의 규칙을 준수하는 한 어떤 유형이든 상관없이 해당 변수의 주소를 "스레드 ID"로 사용합니다. 분명히 arithemetic은 의미가 없지만 통합 유형이 될 것입니다.
후손의 경우 : pthread_self()
a를 반환하고 pid_t
posix입니다. 이것은 휴대용의 일부 정의를 위해 이식 가능합니다.
gettid()
, 거의 확실하게 이식 할 수 없지만 GDB 친화적 인 값을 반환합니다.
나는 이것이 얼마나 빠른지 정말로 모른다. 그러나 이것이 내가 게스트화할 수 있었던 해결책이다.
const size_t N_MUTEXES=128;//UINT_MAX,not 128 for answer to my original question
hash<std::thread::id> h;
cout<<h(std::this_thread::get_id())%N_MUTEXES<<endl;
다시 나는 구조에 대한 포인터를 얻고 unsigned int 또는 uint64_t로 캐스팅하는 것이 답이라고 생각하기 시작했습니다 ... 편집 :
uint64_t get_thread_id()
{
static_assert(sizeof(std::thread::id)==sizeof(uint64_t),"this function only works if size of thead::id is equal to the size of uint_64");
auto id=std::this_thread::get_id();
uint64_t* ptr=(uint64_t*) &id;
return (*ptr);
}
int main()
{
cout<<std::this_thread::get_id()<<" "<<get_thread_id()<<endl;
}
지옥 같은 문제를 방지하기위한 static_assert :) 재 작성은 이런 종류의 버그를 찾는 것에 비해 쉽습니다. :)
이런 식으로 작동해야합니다.
std::stringstream ss;
ss << std::this_thread::get_id();
int id = std::stoi(ss.str());
라이브러리 sstream을 포함하는 것을 잊지 마십시오
thread::native_handle()
에 thread::native_handle_type
대한 typedef 인을 반환 합니다 long unsigned int
.
thread가 기본 생성 된 경우 native_handle ()은 0을 반환합니다. 연결된 OS 스레드가있는 경우 반환 값은 0이 아닙니다 (POSIX의 경우 pthread_t).
그것은 당신이 thread_id를 사용하려는 것에 달려 있습니다. 당신이 사용할 수있는:
std::stringstream ss;
ss << std::this_thread::get_id();
uint64_t id = std::stoull(ss.str());
이것은 당신이 처리하는 고유 ID를 생성합니다. 그러나 한계가 있습니다. 동일한 프로세스의 여러 인스턴스를 시작하고 각 인스턴스가 공통 파일에 스레드 ID를 기록하는 경우 thread_id의 고유성이 보장되지 않습니다. 실제로 중복 될 가능성이 매우 높습니다. 이 경우 다음과 같이 할 수 있습니다.
#include <sys/time.h>
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
uint64_t id = (ts.tv_sec % 1000000000) * 1000000000 + ts.tv_nsec;
이제 시스템 전체에 고유 한 스레드 ID가 보장됩니다.
Maybe this solution be helpful to someone. Call it a first time im main()
. Warning: names
grows indefinitely.
std::string currentThreadName(){
static std::unordered_map<std::thread::id,std::string> names;
static std::mutex mtx;
std::unique_lock<std::mutex> lock(mtx);
auto id = std::this_thread::get_id();
if(names.empty()){
names[id] = "Thread-main";
} else if(names.find(id) == names.end()){
std::stringstream stream;
stream << "Thread-" << names.size();
names[id] = stream.str();
}
return names[id];
}
Another alternative:
#include <atomic>
static std::atomic<unsigned long long> thread_counter;
unsigned long long thread_id() {
thread_local unsigned long long tid = thread_counter++;
return tid;
}
The generated code for this function by g++ in x86 64-bit is just:
_Z9thread_idv:
cmp BYTE PTR fs:_ZGVZ9thread_idvE3tid@tpoff, 0
je .L2
mov rax, QWORD PTR fs:_ZZ9thread_idvE3tid@tpoff
ret
.L2:
mov eax, 1
lock xadd QWORD PTR _ZL14thread_counter[rip], rax
mov BYTE PTR fs:_ZGVZ9thread_idvE3tid@tpoff, 1
mov QWORD PTR fs:_ZZ9thread_idvE3tid@tpoff, rax
ret
_ZGVZ9thread_idvE3tid:
.zero 8
_ZZ9thread_idvE3tid:
.zero 8
I.e. a single branch without any synchronization that will be correctly predicted except for the first time you call the function. After that just a single memory access without synchronization.
A key reason not to use thread::get_id() is that it isn't unique for in a single program/process. This is because the id can be reused for a second thread, once the first thread finishes.
This seems like a horrible feature, but its whats in c++11.
참고URL : https://stackoverflow.com/questions/7432100/how-to-get-integer-thread-id-in-c11
'programing tip' 카테고리의 다른 글
ASP.NET MVC 용 reCaptcha를 구현하는 방법은 무엇입니까? (0) | 2020.10.19 |
---|---|
C # 속성 : 개인 필드없이 사용자 지정 집합 속성을 사용하는 방법은 무엇입니까? (0) | 2020.10.19 |
각도 지시문 이름 : 소문자 만 허용됩니까? (0) | 2020.10.19 |
파이썬에서 두 문자열을 어떻게 비교합니까? (0) | 2020.10.19 |
HighCharts는 범례에서 시리즈 이름을 숨 깁니다. (0) | 2020.10.18 |