有没有一种可移植的方法来用Qt赋予线程名称? [英] Is there a portable way to give thread name with Qt?

查看:491
本文介绍了有没有一种可移植的方法来用Qt赋予线程名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我可以在Linux /a>,它在POSIX系统上更多可用,但仍然缺乏完全的兼容性.

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.

因此,我想采用一些更便携式的方法,也许QThread提供了一些我找不到的方法.有什么办法吗?

So I'd like to have some more portable way, maybe something QThread provides which I've not found. Is there any such way?

推荐答案

QThread API中没有任何内容可以手动管理线程的系统名称,但是,从版本4.8.3开始,Qt将自动设置线程的名称.将您的线程更改为线程对象的名称(QObject::objectName()).

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()).

这在QThread的实现中处理,如下所述.

This is handled in the implementations of QThread as described below.

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());

以及 :

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());

请注意,在Windows上,如果设置了QT_NO_DEBUG,则不会执行上述代码,因此发布模式下将无法运行.

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.

这篇关于有没有一种可移植的方法来用Qt赋予线程名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆