一、线程的创建
1. 创建线程的函数
使用 pthread_create 创建一个线程。pthread_create 函数原型如下:
/*** 创建一个新的线程* @return 成功返回0, 失败返回其他err* @param[out] tidp 线程的tip会写入该内存* @param[in] attr 线程属性* @param[in] start_fn 线程的初始函数* @param[in] arg 线程初始函数的参数*/int pthread_create(pthread_t *tidp,const pthraed_attr_t attr,void *(*start_fn)(void *),void *arg);
线程创建的例子:
#include <pthread.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>/*** 打印当前线程的 pid 和 tid*/void printids(const char *s){pid_t pid;pthread_t tid;pid = getpid();tid = pthread_self();printf("%s: pid %lu, tid %lu\n", s, (unsigned long)pid, (unsigned long)tid);}/*** 线程执行的函数*/void *thr_fn(void *args){printids("thread1");return (void *)0;}int main(){int err;pthread_t tid;err = pthread_create(&tid, NULL, thr_fn, NULL);printids("main thread");sleep(1);exit(0);}
2. 不存在没有线程的进程
值得注意的是:在多线程的语义下,不存在没有线程的进程,即使这个进程没有调用过 pthread_create ,也还是有控制线程/主线程的存在。
如下所示:
int main(){pthread_t tid;tid = pthread_self();printf("main thread tid: %lu\n", (unsigned long)tid);}
二、线程的退出
1. 线程退出的方式
线程退出的方式有三种:
- 使用
return (void *)val退出 - 调用
pthread_exit(void *val)退出 - 被其他线程退出
pthread_cancel()
可以通过 pthread_join 获得线程的退出值pthread_join 函数原型如下:
/*** 等待线程退出* @return 成功返回0,失败返回错误编号* @param[in] 要等待哪个线程退出* @param[out] rval_ptr 存放线程的退出值。由于线程退出值是指针,所有输出参数用的是 void ***/int pthread_join(pthread_t tid, void **rval_ptr);
根据线程终止方式的不同, pthread_join 得到的线程退出值也不同:
- 通过
return方式终止,得到返回值 - 通过
pthread_exit方式终止,线程的退出值就是pthread_exit设置的值 - 通过
pthread_cancel方式被终止,线程退出值就是PTHREAD_CANCELED
2. 线程退出时执行的清理函数
线程可以指定在退出时会执行什么清理函数
相关的接口如下:
void pthread_cleanup_push(void (*rtn)(void *), void *arg);void pthread_cleanup_pop(int execute);
这里了解即可
3. 线程的分离和结合
线程运行结束后要通过 pthread_join 来释放它的资源
可以将线程设置为分离状态( depatched),线程结束时系统自动释放其资源。一般用于主线程不关心线程的返回状态。
线程的状态转变如下:
