objective-c - 在 macOS 上的另一个线程中设置线程的名称

标签 objective-c c multithreading macos pthreads

函数 pthread_setname_np 在 macOS 上只有一个参数并设置当前线程的线程名称。基本上它所做的是调用 proc_info 系统调用,如下所示(代码来自 Apple open-source 页面):

__proc_info(PROC_INFO_CALL_SETCONTROL, getpid(), PROC_SELFSET_THREADNAME, 0, name, length);

但 NSThread 的 setName 方法是在另一个线程中设置线程名称的(唯一)方法(Xcode 和 lldb 显示新名称)。由于没有可用于 NSThread 实现的源代码,我反汇编了 Foundation 框架 (/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation) 并找到了这段代码:

enter image description here

如您所见,它仅使用 pthread_setname_np(似乎仅当 self == [NSThread currentThread] 时才调用它)并且不直接调用 proc_info。我尝试使用 dtruss 调试 setName,发现如果从不同的线程调用,proc_info 系统调用实际上是在 setName 事件上调用的,当对 setName 的调用添加到代码中时,我得到以下行:

proc_info(0x5, 0x15496, 0x2)         = 0 0

那么实际上有没有办法在不同的线程中设置线程名称?它是如何完成的?为什么 setName 的反汇编只有 pthread_setname_np 调用?

附言。我知道可以使用变通方法(蹦床)来传递来自不同线程的名称,然后在必须更改名称的线程内调用 pthread_setname_np,但我对 setName 的实际实现方式很感兴趣。

编辑: 我从两个不同的线程调用 setName,dtruss 输出以下内容(第一列是 pid/tid),0x4f800a (5210122) 是我正在更改名称的线程的 tid:

37555/0x4f800a:        37       6      0 thread_selfid(0x0, 0x0, 0x0)        = 5210122 0
37555/0x4f800a:       218      11      5 proc_info(0x5, 0x92B3, 0x2)    = 0 0
37555/0x4f800a:       243       6      2 proc_info(0x5, 0x92B3, 0x2)    = 0 0

这意味着 proc_info 调用以某种方式挂接到线程的代码中。看起来像是一个 Objective-C 运行时特性。

最佳答案

我在 __proc_info 上添加了一个断点并使用 lldb 运行测试应用程序,在中断时得到以下堆栈:

frame #0: 0x00007fff78401c3c libsystem_kernel.dylib`__proc_info
frame #1: 0x00007fff7853e0b0 libsystem_pthread.dylib`pthread_setname_np + 88
frame #2: 0x00007fff52a7ae88 Foundation`__NSThread__start__ + 1101
frame #3: 0x00007fff7853d6c1 libsystem_pthread.dylib`_pthread_body + 340
frame #4: 0x00007fff7853d56d libsystem_pthread.dylib`_pthread_start + 377
frame #5: 0x00007fff7853cc5d libsystem_pthread.dylib`thread_start + 13

这意味着 pthread_setname_np 实际上是在 NSThread 启动方法中调用的。我在启动 NSThread 后添加了一个 sleep ,然后调用了 setName 并且名称没有更改,因为线程已经启动。这说明了一切。所以不可能在不同的线程上更改线程名称。

关于objective-c - 在 macOS 上的另一个线程中设置线程的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48969267/

相关文章:

ios - 何时适合使用自动续订订阅 - iOS

c - Minix - 将数据从系统调用地址复制回调用进程

c - 重定向执行 shellcode 的程序的输出

c - 为什么读/写锁需要锁?

ios - MPVolumeView 动画问题

objective-c - Mac 应用程序中的 Facebook

objective-c - 通过 ObjC 类别覆盖方法并调用默认实现?

c - 可以将用户内存中的字符串传递给 printk 吗?

c++ - 将 QVector 作为 arg 传递给 QRunnable

PHP线程池?