C++11 'native_handle' is not a member of 'std::this_thread'
There is no way for a thread to autonomously gain access to its own std::thread
. This is on purpose since std::thread
is a move-only type.
I believe what you're requesting is a native_handle()
member of std::thread::id
, and that is an interesting suggestion. As far as I know it is not currently possible. It would be used like:
void foo()
{
auto native_me = std::this_thread::get_id().native_handle();
// ...
}
It wouldn't be guaranteed to work, or even exist. However I imagine most POSIX platforms could support it.
One way to try to change the C++ standard is to submit issues. Here are directions on how to do so.
How to handle a PostMessageThread message in std::thread?
What std::thread::native_handle()
returns is implementation-defined (per [thread.req.native] in the C++ standard). There is no guarantee that it even returns a thread ID that PostThreadMessage()
wants.
For instance, MSVC's implementation of std::thread
uses CreateThread()
internally, where native_handle()
returns a Win32 HANDLE
. You would have to use GetThreadId()
to get the thread ID from that handle.
Other implementations of std::thread
might not use CreateThread()
at all. For instance, they could use the pthreads
library instead, where native_handle()
would return a pthread_t
handle, which is not compatible with Win32 APIs.
A safer way to approach this issue is to not use native_handle()
at all. Call GetCurrentThreadId()
inside of your thread function itself, saving the result to a variable that you can then use with PostThreadMessage()
when needed, for example:
struct threadInfo
{
DWORD id;
std::condition_variable hasId;
};
void threadFunc(threadInfo &info)
{
info.id = GetCurrentThreadId();
info.hasId.notify_one();
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
// Doing appropriate stuff after receiving the message.
}
}
...
threadInfo info;
std::thread t(threadFunc, std::ref(info));
info.hasId.wait();
...
PostThreadMessage(info.id, WM_CUSTOM_MESSAGE, 0, 0);
WindowsWhy does std::thread::native_handle return a value of type 'long long unsigned int' instead of void* (a.k.a. HANDLE)?
The returned "handle" is the thread id not the HANDLE
as returned by CreateThread
.
You need to use OpenThread
to get a handle from the id.
How to pass std::thread as thread id in PostThreadMessage?
You can get the underlying, "Windows-style" thread handle for a std::thread
object by calling its native_handle()
member function. From that, you can retrieve the thread's ID by calling the GetThreadId
WinAPI function, and passing that native handle as its argument.
Here's a short code snippet that may be what you'd want in the case you've outlined:
auto tHandle = thread_not_main.native_handle(); // Gets a "HANDLE"
auto tID = GetThreadId(tHandle); // Gets a DWORD ID
if (msg.message == WM_PAINT) {
PostThreadMessage(tID, msg, wParam, lParam);
}
else {
DispatchMessage(&msg);
}
//...
How to retrieve the thread id from a boost::thread?
Boost includes an operator<<(std::ostream&, const boost::thread::id&)
overload that can be used to write a thread id to a stream (actually, the overload is a template and will work with any specialization of std::basic_ostream
, not just std::ostream
).
The result of printing the id is likely platform-specific, since different platforms may use different internal representations for thread identifiers.
Getting Native Handle from Within a Thread?
#include <mutex>
#include <condition_variable>
#include <iostream>
#include <atomic>
#include <thread>
class threadContainer {
std::thread* mT;
std::mutex m;
void lockMe() {
// wait for mT to be assigned:
{
std::unique_lock<std::mutex> lock(m);
}
std::cout << "lockMe():" << mT << "\n";
auto h = mT->native_handle();//causes a crash
std::cout << "Done lockMe!\n";
}
public:
void run() {
// release lock only after mT assigned:
{
std::unique_lock<std::mutex> lock(m);
mT = new std::thread( [&](){ this->lockMe(); } );
}
std::cout << "run():" << mT << "\n"; //00326420
mT->join();
}
};
int main() {
threadContainer mContainer;
mContainer.run();
return 0;
}
Try that.
How to set custom name of this thread?
Unless portability is wanted, and the target is only POSIX systems with POSIX threads, the id could easily be obtained with pthread_self
.
MinGW error: ‘thread’ is not a member of ‘std’
This error means that the STL you are using does not contain all the features of C++11.
To access C++11 threads in Windows, you will need a build of Mingw with posix-threads. Here you can find Mingw-Builds v4.8.1: http://sourceforge.net/projects/mingwbuilds/files/host-windows/releases/4.8.1/64-bit/threads-posix/sjlj/
Related Topics
String Comparison with the Most Similar String
Convert Shared Library to Static Library
Duplicate Const Qualifier Allowed in C But Not in C++
How to Implement "_Mm_Storeu_Epi64" Without Aliasing Problems
What Is the Cin Analougus of Scanf Formatted Input
Freopen() Equivalent for C++ Streams
Or Is Not Valid C++:Why Does This Code Compile
Is Nan a Valid Key Value for Associative Containers
Where Does the _1 Symbol Come from When Using Llvm's Libc++
Mapping Elements in 2D Upper Triangle and Lower Triangle to Linear Structure
Why Can't I Return Bigger Values from Main Function
Visual Studio 2013: Cl.Exe Exited with Code -1073741515
What's the Difference Between Getline and Std::Istream::Operator>>()
Inconsistent Use of Const Qualifier Between Declaration and Definition
How to Print Boost::Any to a Stream
Can't Access Derived Class Method from Pointer of Type Base Class