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.