1

我一直在尝试找到 iOS 上的 pthread 和调度队列之间的关联。例如,给定一个pthread_t对象,是否有可能找出关联的调度队列(如果有的话)?

我见过各种各样的*get_current_*()API *get_specific_*()—— 只有当我知道以前使用的键来设置上下文,或者我已经有一个dispatch_queue_t对应于我想要其标签的调度队列时,它们才有用。

我正在寻找的只是获取所有调度队列的列表(私有/串行的 - 在应用程序中创建),以便我可以通过某种方式获取dispatch_queue_t对象,从而使用这些来查找与该应用程序线程的关联处理并因此打印他们的名字。

编辑(我在考虑 Das 的建议后得到的解决方案 - thread_info():我得到了调度队列的名称!我不得不使用thread_info()来掌握dispatch_qaddr每个线程。然后,我将其内容dispatch_qaddr类型处理为类型uint64_t(dispatch_queue_t *)并根据需要取消引用以传递给以dispatch_queue_get_label()获取标签。这里的技巧是以安全的方式检查给定时间点的线程是否正在执行调度队列的代码块。dispatch_queue_get_label()否则,对我们传递的对象所做的内部操作可能会使应用程序崩溃。所以,我不得不使用一些特定于平台的 API 来验证结果对象内容的有效性是否正确 size: sizeof(dispatch_queue_t),假设dispatch_queue_t是不透明的类型。是的,我很高兴看到我想要的!干杯! \米/

4

2 回答 2

3

获取进程中所有调度队列列表的唯一方法是通过堆遍历,例如使用该heap工具:

$ heap -addresses OS_dispatch_queue MyApp

或通过 malloc introspection API 实现的编程等效项,参见malloc/malloc.h

这是因为空闲/挂起的队列实际上只是内存中的对象,仅由创建它们/引用它们的人跟踪,没有队列的中央“注册表”。

有一种工具可以找到当前与线程关联的运行队列,但它仅适用于调试器、crashreporters 等,cf mach/thread_info.h

从中获得的thread_identifier_info结构thread_info(thread, THREAD_IDENTIFIER_INFO, ...)包含一个dispatch_qaddr字段,该字段具有当前与相关(mach)线程关联的队列。

请注意,除非以这种方式检查的线程被挂起(调试器正在使用该调用时就是这种情况),否则您从此 API 获得的信息将立即失效(线程可能已经切换到处理另一个队列),并且返回的队列指针可能是悬空的(如果队列所有者同时释放了它)。

一般来说,没有安全/有用的方法可以thread_info从正在运行的进程内部使用上面提到的 API 或 malloc 自省 API 来自省其自己的线程。堆,这些 API 纯粹是供进程外调试工具使用的。

于 2013-07-12T06:21:40.580 回答
1

一般来说,线程和队列之间没有固定的关联。GCD 管理一个线程池,通常任何线程都可以从任何队列运行一个块。唯一的例外是主队列总是在主线程上运行它的块,而主线程只运行来自主队列的块。

没有 API 可以询问“哪个队列正在其他线程上运行”,因为答案可能会在您询问后立即改变。在调度的块内,您可以请求当前队列,从而知道当前线程上正在运行的队列,但是一旦该块返回,该答案可能会变得无效。

于 2013-07-11T16:52:12.287 回答