线程创建的函数及应用小结

打印 上一主题 下一主题

主题 843|帖子 843|积分 2529

进程是盘算机分配资源的基本单位,线程是cpu调度的基本单位
线程基本概念:

LWP:light weight process 轻量级的进程。创建线程的底层函数和进程一样,都是clone,因此线程的本质仍是进程(在linux情况下)
与进程相比,线程有独立的TCB结构体(类似于进程的PCB),但没有独立的所在空间(共享),类似于合租与独居。
查察线程号(LWP,不是TID)可以用下述下令:
  1. ps -Lf xxx(PID)
复制代码
线程创建相关函数
  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. //=================================属性设置按需要采用,若普通情况可以不用设置===============//
  5. pthread_attr_t attr;                                // 定义线程的属性变量
  6. int pthread_attr_init(pthread_attr_t *attr);        // 初始化属性变量
  7. int pthread_attr_setXXX(pthread_attr_t *attr, ...); // 设置属性变量的值
  8. //此处仅列举常用的//
  9. int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); // 设置/获得线程的分离属性
  10. int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
  11. int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched); // 设置/获得是否继承创建者的调度策略
  12. int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched);
  13. int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); // 设置/获得调度策略
  14. int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
  15. int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param); // 设置/获得线程的静态优先级
  16. int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);
  17. //=================================上述属性设置按需要采用,若普通情况可以不用设置===============//
  18. int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
  19. // 创建线程,此处void *(*start_routine)(void *)函数指针指向的函数,void *arg作为其参数,并且需要采用值传递,如果数据类型不同需要强转
  20. int pthread_detach(pthread_t thread); // 如果没有设置线程的分离属性,可以用此函数强制设为分离属性,防止线程结束后变为僵尸进程,无法释放资源,而且不能再用 pthread_join等待回收该进程的资源
  21. pthread_t pthread_self(void);         // 创建成功后,可以在线程中使用,获取当前线程的tid
  22. void pthread_exit(void *retval);      // 退出线程,并得到返回值retval
  23. int pthread_cancel(pthread_t thread); // 给指定线程发送一个取消的请求
  24. int pthread_setcancelstate(int state, int *oldstate);
  25. // 设置线程的取消状态:PTHREAD_CANCEL_ENABLE 可取消; PTHREAD_CANCEL_DISABLE 不可取消
  26. int pthread_setcanceltype(int type, int *oldtype);
  27. // 设置线程的取消类型:PTHREAD_CANCEL_DEFERRED 延时响应; PTHREAD_CANCEL_ASYNCHRONOUS 立即响应。
  28. int pthread_join(pthread_t thread, void **retval); // 接合指定已结束或者待结束的线程,并得到返回状态值;如果指定的线程还在运行,将会阻塞等待。
复制代码
应用实例
  1. char *retval = "byebye!\n"; // 假设为共享资源
  2. pthread_mutex_t m;          // 定义互斥锁
  3. void handler(void *arg)
  4. {
  5.     pthread_mutex_unlock(&m);
  6. }
  7. void *child_thread(void *arg)
  8. {
  9.     while (1)
  10.     {
  11.         pthread_cleanup_push(handler, NULL); // 上锁前,需要将handler函数压入线程取消处理的栈中,以防止该子进程在运行的中途被取消,造成死锁
  12.         pthread_mutex_lock(&m);
  13.         printf("Child thread obtain the mutex:%s\n", retval);
  14.         pthread_mutex_unlock(&m);
  15.         pthread_cleanup_pop(0); // 解锁后,将handler从栈中弹出,不执行
  16.         sleep(2);
  17.     }
  18. }
  19. int main()
  20. {
  21.     pthread_mutex_init(&m, NULL);
  22.     pthread_t tidofparent = pthread_self(); // 接收主线程的tid值。
  23.     printf("parent's tid:%ld\n", tidofparent);
  24.     printf("parent's tid:%ld\n", sizeof(int));
  25.     pthread_t tid;
  26.     pthread_create(&tid, NULL, child_thread, NULL); // 新建子线程
  27.     // pthread_detach(tid); 让线程“自立门户”,结束后资源自动回收,此处与pthread_cancel和pthread_join冲突,
  28.     sleep(5);
  29.     pthread_cancel(tid); // 5秒后,向子线程发送取消的请求
  30.     // 待子线程被取消后,锁被handler自动释放,可以继续加互斥锁,对公共资源进行操作
  31.     pthread_mutex_lock(&m);
  32.     retval = "I'm main pthread!\n";
  33.     printf("Now I botain the mutex:%s\n", retval);
  34.     pthread_mutex_unlock(&m);
  35.     /*
  36.     void *p;
  37.     pthread_join(tid, &p); // 如果没有采用pthread_cancel(tid)取消子进程,这部分将会阻塞等待子线程结束,接受子线程的返回值并打印
  38.     printf("子线程的返退出回值:%s\n", (char *)p);
  39. */
  40.     return 0;
  41. }
复制代码
注意事项

1.主线程退出也可以用pthread_exit(),其他子线程还是运行不受影响。但如果主线程运行了return/exit等语句,或者子线程用exit,会导致整个进程退出。
2.制止线程编程僵尸进程的三种方法:

  • int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) 提前设置分离属性
  • int pthread_detach(pthread_t thread);子线程创建后强制设置分离属性
  • 在线程竣事后利用pthread_join()进行接合。
3.malloc 和mmap 申请的内存可以被其他子线程释放,因为申请出来的都是共享堆所在。
4.信号语义复杂,只管制止和线程机制混用。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

灌篮少年

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表