一、线程的创建

1. 创建线程的函数

使用 pthread_create 创建一个线程。
pthread_create 函数原型如下:

  1. /**
  2. * 创建一个新的线程
  3. * @return 成功返回0, 失败返回其他err
  4. * @param[out] tidp 线程的tip会写入该内存
  5. * @param[in] attr 线程属性
  6. * @param[in] start_fn 线程的初始函数
  7. * @param[in] arg 线程初始函数的参数
  8. */
  9. int pthread_create(pthread_t *tidp,
  10. const pthraed_attr_t attr,
  11. void *(*start_fn)(void *),
  12. void *arg);

线程创建的例子:

  1. #include <pthread.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. /**
  6. * 打印当前线程的 pid 和 tid
  7. */
  8. void printids(const char *s)
  9. {
  10. pid_t pid;
  11. pthread_t tid;
  12. pid = getpid();
  13. tid = pthread_self();
  14. printf("%s: pid %lu, tid %lu\n", s, (unsigned long)pid, (unsigned long)tid);
  15. }
  16. /**
  17. * 线程执行的函数
  18. */
  19. void *thr_fn(void *args)
  20. {
  21. printids("thread1");
  22. return (void *)0;
  23. }
  24. int main()
  25. {
  26. int err;
  27. pthread_t tid;
  28. err = pthread_create(&tid, NULL, thr_fn, NULL);
  29. printids("main thread");
  30. sleep(1);
  31. exit(0);
  32. }

2. 不存在没有线程的进程

值得注意的是:在多线程的语义下,不存在没有线程的进程,即使这个进程没有调用过 pthread_create ,也还是有控制线程/主线程的存在。
如下所示:

  1. int main()
  2. {
  3. pthread_t tid;
  4. tid = pthread_self();
  5. printf("main thread tid: %lu\n", (unsigned long)tid);
  6. }

二、线程的退出

1. 线程退出的方式

线程退出的方式有三种:

  • 使用 return (void *)val 退出
  • 调用 pthread_exit(void *val) 退出
  • 被其他线程退出 pthread_cancel()

可以通过 pthread_join 获得线程的退出值
pthread_join 函数原型如下:

  1. /**
  2. * 等待线程退出
  3. * @return 成功返回0,失败返回错误编号
  4. * @param[in] 要等待哪个线程退出
  5. * @param[out] rval_ptr 存放线程的退出值。由于线程退出值是指针,所有输出参数用的是 void **
  6. */
  7. int pthread_join(pthread_t tid, void **rval_ptr);

根据线程终止方式的不同, pthread_join 得到的线程退出值也不同:

  • 通过 return 方式终止,得到返回值
  • 通过 pthread_exit 方式终止,线程的退出值就是 pthread_exit 设置的值
  • 通过 pthread_cancel 方式被终止,线程退出值就是 PTHREAD_CANCELED

2. 线程退出时执行的清理函数

线程可以指定在退出时会执行什么清理函数
相关的接口如下:

  1. void pthread_cleanup_push(void (*rtn)(void *), void *arg);
  2. void pthread_cleanup_pop(int execute);

这里了解即可

3. 线程的分离和结合

线程运行结束后要通过 pthread_join 来释放它的资源
可以将线程设置为分离状态( depatched),线程结束时系统自动释放其资源。一般用于主线程不关心线程的返回状态。
线程的状态转变如下:
线程使用.png

资源

线程使用.drawio