线程由线程号进行标识。线程号仅在线程所属的进程环境中有效。也就是说属于不同进程的两个线程可能线程号一样。
线程标识用结构体pthread_t tid表示。与线程Id相关的函数如下:
比较两个线程ID:
#include <pthread.h>
int pthread_equal(pthread_t tid1,pthread_t tid2);
Returns: nonzero if equal, 0 otherwise
获取自身线程ID:
#include <pthread.h>
pthread_t pthread_self(void);
Returns: the thread ID of the calling thread
创建和终止进程:
创建线程:
#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr,
void *(*start_rtn)(void *), void *restrict arg);
Returns: 0 if OK, error number on failure
tidp: 线程ID
attr:定制线程属性
start_rtn:新线程从start_rtn指向的函数开始执行
arg:传入start_rtn指向函数的参数
线程终止:
线程有三种终止方式:
1)从启动例程返回(return),返回值为线程退出码2)被同进程的其他线程取消3)调用pthread_exit
1)调用pthread_exit
#include <pthread.h> void pthread_exit(void *rval_ptr);
启动例程调用pthread_exit 可以退出线程。rval_ptr可以被其他线程通过pthread_join访问到
#include <pthread.h>
int pthread_join(pthread_t thread,void **rval_ptr);
Returns: 0 if OK, error number on failure
pthread_join 使线程发生阻塞,知道thread指向的线程终止,rval_ptr用于获取终止线程的返回值。如果线程是通过被取消的方式结束,则返回值被置为PTHREAD_CANCELED。
2)被同进程其他线程取消
#include <pthread.h> int pthread_cancel(pthread_t tid); Returns: 0 if OK, error number on failure
3)线程的清理
线程可以构建线程清理程序栈来自定义线程清理程序。(栈:后进先出)
#include <pthread.h> void pthread_cleanup_push(void (*rtn)(void *), void *arg); void pthread_cleanup_pop(int execute);
在三种情况之一,线程清理程序栈被调用
a.线程调用pthread_exitb.应答其他线程的cancellation请求c.execute参数非0
具体使用见后面的example
执行结果
windeal@ubuntu:~/Windeal/apue$ ./exe thread 2 start thread 2 push complete cleanup: thread 2 second handler cleanup: thread 2 first handler thread 1 start thread 1 push complete cleanup: thread 1 second handler thread 1 exit code 1 thread 2 exit code 2 windeal@ubuntu:~/Windeal/apue$