iOS系统经过Core Services层的Foundation框架提供基于OC语言的NSThread和NSOperationQueue类来实现对线程和线程池的管理和使用。同时也提供了一套基于C语言的GCD线程池函数库来支持多线程的处理应用。这些高级的线程类或者函数的内部实现大部分最终都会调用POSIX标准中的pthread线程库中的pthread_xxx系列函数(#include <pthread.h>)来完成线程的建立、运行、暂停、恢复、销毁、结束等操做。用户态下的线程建立经过系统调用到达内核态的BSD层并建立bsdthread对象,而BSD层则调用Mach层的ksthread对象来完成最终线程的建立和调度的。 git
pthread库中除了提供一系列标准的线程操做API外,还提供了一个用于监控线程建立、运行、结束、销毁的内省函数(单词introspection翻译为内省,但我以为叫拦截器可能更好一些)。这个函数定义在头文件#include <pthread/introspection.h>
中,函数的签名为:github
pthread_introspection_hook_t pthread_introspection_hook_install(pthread_introspection_hook_t hook)
复制代码
函数的做用是安装一个回调函数来挂钩线程生命周期的四个过程。所以函数的入参是一个函数指针,返回的则是老的挂钩函数的指针。回调函数是一个格式为pthread_introspection_hook_t类型的函数,其格式定义以下:bash
typedef void (*pthread_introspection_hook_t)(unsigned int event, pthread_t thread, void *addr, size_t size);
复制代码
回调函数的每一个参数的意义以下:多线程
event:指定线程所处的状态。架构
thread: 线程的句柄,每一个pthread线程都由一个pthread_t类型句柄来惟一标识。app
addr: 为线程分配的栈内存的基地址。框架
size: 为线程分配的栈内存的尺寸。函数
上面说的每个线程有建立、运行、终止、销毁四个状态,而event则是用来表示线程的四种状态的值,它的值是以下枚举结构的某一个值:ui
enum {
PTHREAD_INTROSPECTION_THREAD_CREATE = 1, //建立
PTHREAD_INTROSPECTION_THREAD_START, //运行
PTHREAD_INTROSPECTION_THREAD_TERMINATE, //终止
PTHREAD_INTROSPECTION_THREAD_DESTROY, //销毁
};
复制代码
须要注意的是在内省函数中设置回调挂钩函数后只会监控设置以后的全部线程状态的变化。所以若是咱们要监控整个应用生命周期的全部线程的状态时,须要尽量早的进行回调函数的设置,好比能够在某个类的+load方法中,或者在某个全局C++对象的构造函数中设置等等。spa
回调挂钩函数中的第二个参数thread是一个类型为pthread_t线程句柄对象,这个对象的结构并无对外公开。可是由于pthread库已经被苹果开源:opensource.apple.com/source/libp… 。所以咱们能够经过线程句柄对象的内部定义来获取关于线程的更多信息。以方便咱们能对线程的各类数据进行更加详细的记录。固然这里咱们须要考虑到线程句柄的不一样版本下的数据成员的问题。
最后咱们实现一个简单的在main函数内实现线程监控的代码示例:
#include <pthread/introspection.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
pthread_introspection_hook_t g_oldpthread_introspection_hook = NULL;
void mypthread_introspection_hook(unsigned int event, pthread_t thread, void *addr, size_t size)
{
__uint64_t threadid;
pthread_threadid_np(thread, &threadid);
printf("thread_id = %d, addr = %p, size = %d\n", threadid, addr, size);
switch (event)
{
case PTHREAD_INTROSPECTION_THREAD_CREATE:
//dothing ..
break;
case PTHREAD_INTROSPECTION_THREAD_START:
//dothing ..
break;
case PTHREAD_INTROSPECTION_THREAD_TERMINATE:
//dothing ..
break;
case PTHREAD_INTROSPECTION_THREAD_DESTROY:
//dothing ..
break;
}
//记得在最后或者开头调用老的hook函数
if (g_oldpthread_introspection_hook != NULL)
g_oldpthread_introspection_hook(event, thread, addr, size);
}
int main(int argc, char *argv[])
{
//注册线程监控的回调函数为mypthread_introspection_hook
g_oldpthread_introspection_hook = pthread_introspection_hook_install(mypthread_introspection_hook);
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
复制代码
你能够经过开源代码中对pthread_t类型结构体的定义来获取线程的更多信息,可是要注意线程库的版本信息。
线程监控回调函数中的代码应该尽量的精简和高效,包括官方的头文件中也有一段说明(其实是能够被appstore审核经过的):
This should only be used for introspection and debugging tools. Do not rely on it in shipping code.
欢迎你们访问欧阳大哥2013的github地址