Linux系统编程之线程API总结
目录Linux系统编程之线程API总结一、pthread_self、pthread_equal 线程ID二、pthread_create 创建一个新的线程三、pthread_exit 终止调用它的线程四、pthread_join 回收线程五、pthread_cancel 向一个指定的线程发送、接收取消请求六、pthread_setcancelstate、pthread_setcanceltype 设置线程的取消性状态和类型七、pthread_detach 分离线程八、pthread_cleanup_push添加、pthread_cleanup_pop移除线程清理处理函数九、pthread_attr_setstack 设置、pthread_attr_getstack 获取线程栈属性Linux系统编程之线程API总结一、pthread_self、pthread_equal 线程ID#include pthread.h // 返回当前线程的线程 ID pthread_t pthread_self(void); // 检查两个线程 ID 是否相等返回0表示不相等 int pthread_equal(pthread_t t1, pthread_t t2);二、pthread_create 创建一个新的线程#include pthread.h int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);thread新创建的线程的线程 ID 会保存在参数 thread 所指向的内存中后续的线程相关函数会使用该标识来引用此线程。attr指向 pthread_attr_t 类型的缓冲区pthread_attr_t 数据类型定义了线程的各种属性attr 设置为 NULL那么表示将线程的所有属性设置为默认值以此创建新线程。start_routine一个函数指针指向一个函数新创建的线程从 start_routine()函数开始运行该函数返回值类型为void *并且该函数的参数只有一个void *其实这个参数就是pthread_create()函数的第四个参数 arg。如果需要向 start_routine()传递的参数有一个以上那么需要把这些参数放到一个结构体中然后把这个结构体对象的地址作为 arg 参数传入。arg传递给 start_routine()函数的参数。NULL 表示不传入参数返回值成功返回 0失败时将返回一个错误号并且参数 thread 指向的内容是不确定的。三、pthread_exit 终止调用它的线程#include pthread.h void pthread_exit(void *retval);retval指定了线程的返回值、也就是线程的退出码Tips如果主线程调用了 pthread_exit()那么主线程也会终止但其它线程依然正常运行直到进程中的所有线程终止才会使得进程终止。四、pthread_join 回收线程#include pthread.h int pthread_join(pthread_t thread, void **retval);thread需要等待的线程 IDretval如果对目标线程的终止状态不感兴趣则可将参数 retval 设置为 NULL。如果参数 retval 不为 NULL则 pthread_join()将目标线程的退出状态即目标线程通过pthread_exit()退出时指定的返回值或者在线程 start 函数中执行 return 语句对应的返回值复制到retval 所指向的内存区域如果目标线程被 pthread_cancel()取消则将 PTHREAD_CANCELED 放在retval 中。返回值成功返回 0失败将返回错误码。Tips调用 pthread_join()函数将会以阻塞的形式等待指定的线程终止如果该线程已经终止则 pthread_join() 立刻返回。如果多个线程同时尝试调用 pthread_join()等待指定线程的终止那么结果将是不确定的。若线程并未分离则必须使用 pthread_join()来等待线程终止回收线程资源如果线程终止后其它线程没有调用 pthread_join()函数来回收该线程那么该线程将变成僵尸线程与僵尸进程的概念相类似同样僵尸线程除了浪费系统资源外若僵尸线程积累过多那么会导致应用程序无法创建新的线程。五、pthread_cancel 向一个指定的线程发送、接收取消请求#include pthread.h // 发送取消请求 int pthread_cancel(pthread_t thread); // 接收取消请求 void pthread_testcancel(void);thread需要取消的目标线程 ID返回值成功返回 0失败将返回错误码。六、pthread_setcancelstate、pthread_setcanceltype 设置线程的取消性状态和类型#include pthread.h int pthread_setcancelstate(int state, int *oldstate); int pthread_setcanceltype(int type, int *oldtype);state是如下值PTHREAD_CANCEL_ENABLE线程可以取消这是新创建的线程取消性状态的默认值PTHREAD_CANCEL_DISABLE线程不可被取消如果此类线程接收到取消请求则会将请求挂起直至线程的取消性状态变为PTHREAD_CANCEL_ENABLE七、pthread_detach 分离线程#include pthread.h int pthread_detach(pthread_t thread);thread需要分离的线程 ID返回值成功将返回 0失败将返回一个错误码。Tips一旦线程处于分离状态就不能再使用 pthread_join()来获取其终止状态此过程是不可逆的一旦处于分离状态之后便不能再恢复到之前的状态。处于分离状态的线程当其终止后能够自动回收线程资源。八、pthread_cleanup_push添加、pthread_cleanup_pop移除线程清理处理函数#include pthread.h // 添加一个清理函数 void pthread_cleanup_push(void (*routine)(void *), void *arg); // 将清理函数栈中最顶层也就是最后添加的函数最后入栈的函数移除 void pthread_cleanup_pop(int execute);routine一个函数指针指向一个需要添加的清理函数routine()函数无返回值只有一个 void *类型参数arg参数 arg 作为 routine()函数的参数Tips当线程执行以下动作时清理函数栈中的清理函数才会被执行线程调用 pthread_exit()退出时、线程响应取消请求时、用非 0 参数调用pthread_cleanup_pop()。除了以上三种情况之外其它方式终止线程将不会执行线程清理函数譬如在线程 start 函数中执行 return 语句退出时不会执行清理函数。九、pthread_attr_setstack 设置、pthread_attr_getstack 获取线程栈属性#include pthread.h int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize); int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize);attr指向线程属性对象stackaddr栈起始地址stacksize栈大小返回值成功返回 0失败将返回一个非 0 值的错误码OK这是线程的API调用总结参考正点原子的《Linux C 应用编程参考手册》