I know I can set thread name (the one visible in gdb and htop) in Linux using prctl()
. But with another OSes this most likely won't work. Also, I could try using pthread_setname_np()
, which is a bit more available across POSIX systems, but still lacks full compatibility.
So I'd like to have some more portable way, maybe something QThread
provides which I've not found. Is there any such way?
There's nothing in the QThread
API to manually manage the system name of the thread, however, since version 4.8.3, Qt will automatically set the name of your thread to the name of the thread object (QObject::objectName()
).
This is handled in the implementations of QThread
as described below.
You have something like this in qthread_unix.cpp
:
#if (defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_QNX))
static void setCurrentThreadName(pthread_t threadId, const char *name)
{
# if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE)
Q_UNUSED(threadId);
prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);
# elif defined(Q_OS_MAC)
Q_UNUSED(threadId);
pthread_setname_np(name);
# elif defined(Q_OS_QNX)
pthread_setname_np(threadId, name);
# endif
}
#endif
/*
* [...]
*/
QString objectName = thr->objectName();
if (Q_LIKELY(objectName.isEmpty()))
setCurrentThreadName(thr->d_func()->thread_id, thr->metaObject()->className());
else
setCurrentThreadName(thr->d_func()->thread_id, objectName.toLocal8Bit());
And the equivalent in qthread_win.cpp
:
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // must be 0x1000
LPCSTR szName; // pointer to name (in user addr space)
HANDLE dwThreadID; // thread ID (-1=caller thread)
DWORD dwFlags; // reserved for future use, must be zero
} THREADNAME_INFO;
void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
{
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = threadName;
info.dwThreadID = threadId;
info.dwFlags = 0;
__try
{
RaiseException(0x406D1388, 0, sizeof(info)/sizeof(DWORD), (const ULONG_PTR*)&info);
}
__except (EXCEPTION_CONTINUE_EXECUTION)
{
}
}
/*
* [...]
*/
QByteArray objectName = thr->objectName().toLocal8Bit();
qt_set_thread_name((HANDLE)-1, objectName.isEmpty() ? thr->metaObject()->className() : objectName.constData());
Note that on Windows, the above code won't be executed if QT_NO_DEBUG
is set, thus it won't work in Release mode.
In Qt documentation you can find:
To choose the name that your thread will be given (as identified by the command ps -L on Linux, for example), you can call setObjectName() before starting the thread. If you don't call setObjectName(), the name given to your thread will be the class name of the runtime type of your thread object (for example, "RenderThread" in the case of the Mandelbrot Example, as that is the name of the QThread subclass). Note that this is currently not available with release builds on Windows.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With