多线程的开发和应用在平时的项目中使用非常频繁。Linux C++中,一般使用pthread库操作线程相关业务,不少公司一般都会基于该线程库的基本接口进行封装,使用起来更加方便易用。本文对该线程库的常用接口和使用方法做个介绍。

一、创建线程前的工作——设置线程属性

1、线程属性结构体的成分

线程具有属性,属性结构体用pthread_attr_t表示。它的结构如下:

typedef struct
{int detachstate;                  //线程的分离状态int schedpolicy;                  //线程的调度策略structsched_param schedparam;     //线程的调度参数int inheritsched;                 //线程的继承性int scope;                        //线程的作用域size_t guardsize;                 //线程栈末尾的警戒缓冲区大小int stackaddr_set;                //线程的栈设置void* stackaddr;                  //线程栈的位置size_t stacksize;                 //线程栈的大小
}pthread_attr_t;

2、属性初始化接口

提供的接口:

int pthread_attr_init(pthread_attr* attr);

使用时,首先要先对这个结构体进行初始化,在使用后需要对其反初始化。

3、属性反初始化接口

提供的接口:

int pthread_attr_destroy(pthread_attr_t* attr);

同上一点的初始化,使用结束后的销毁。

4、设置、获取线程作用域属性scope接口

提供的接口:

int pthread_attr_setscope(pthread_attr_t*, int);int pthread_attr_getscope(const pthread_attr_t*, int*);

作用域属性表示线程间竞争CPU的范围,也就是说线程优先级的有效范围。具体可以选择两个值,PTHREAD_SCOPE_SYSTEM和PTHREAD_SCOPE_PROCESS。前者表示与系统中所有线程一起竞争CPU时间,后者表示仅与同进程中的线程竞争CPU,默认的一般都是PTHREAD_SCOPE_PROCESS。

5、设置、获取线程分离状态属性detachstate接口

提供的接口:

int pthread_attr_setdetachstate(pthread_attr_t*, int);int pthread_attr_getdetachstate(const pthread_attr_t*, int*);

在任何一个时间点上,线程是可结合的(joinable),或者是可分离的(detached),一个可结合的线程能够被其他线程收回其资源和杀死,在被其他线程回收之前,它的存储器资源(如栈)是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。默认情况下,线程是非分离状态的。这种情况下,原有的线程等待创建的线程结束,只有当pthread_join()函数返回时,创建的线程才算终止,才能释放自己占用的系统资源。这两种状态的值分别是PTHREAD_CREATE_DETACHED(可分离线程)和PTHREAD_CREATE_JOINABLE(非分离线程),默认是PTHREAD_CREATE_JOINABLE。

6、设置、获取线程调度参数接口

提供的接口:

int pthread_attr_setschedparam(pthread_attr_t* restrict, const struct sched_param* param);int pthread_attr_getschedparam(pthread_attr_t* restrict, const struct sched_param* param);

接口中的struct sched_param结构体仅仅包含一个成员变量sched_priority,大的优先权值对应高的优先权,系统支持的最大和最小优先权值可以用sched_get_priority_max和sched_get_priority_min分别得到。但是在一般情况下,若不是写实时程序,不建议修改线程的优先级,因为调度策略是一个复杂的事情,如果不正确使用会导致程序错误,从而导致死锁问题,普通线程一般不用设置。

7、设置、获取线程的调度策略接口

提供的接口:

int pthread_attr_setschedpolicy(pthread_attr_t*, int);int pthread_attr_getschedpolicy(const pthread_attr_t*, int*);

Linux线程调度策略及优先级说明:

Linux系统下任务调度策略一般有三种:

SCHED_OTHER:普通任务调度策略。

SCHED_FIFO:实时任务调度策略,先到先服务。一旦占用CPU则一直运行,知道有更高优先级任务到达或自己放弃。

SCHED_RR:实时任务调度策略,时间片轮转。当任务的时间片用完,系统将重新分配时间片,并置于就绪队列尾。普通线程一般设置SCHED_OTHER。

8、设置、获取线程的继承调度

提供的接口:

int pthread_attr_setinheritsched(pthread_attr_t*. int);int pthread_attr_getinheritsched(const pthread_attr_t*. int*);

线程的继承调度主要是设置线程是否继承父线程的调度,也就是说此线程的调度策略及优先级是否继承于父线程。可以选择两个值:PTHREAD_INHERIT_SCHED和PTHREAD_EXPLICIT_SCHED,默认情况下,普通线程是继承于父线程的。设置好属性之后,接下来就是线程的创建了。

二、创建线程

创建线程接口:

int pthread_create(pthread_t *thread, const pthread_attr_t* attr, void* (*start_routine)(void *), void* arg);

参数说明:

参数一为指向线程标识符的指针,也就是线程句柄。

参数二为设置的线程属性,就是上面第一节中通过接口设置的属性结构体。

参数三为线程运行函数的地址,也就是线程执行体的函数指针。

参数四为线程运行函数的参数。

使用该接口创建线程时,若不指定分配堆栈大小,系统会分配默认值。在Linux中,使用ulimit -s可以查看默认值的大小。Linux默认分配8192KB也就是8M内存。一般来说,默认堆栈是8192KB,最小为16KB。如果在创建线程时,出现内存不足问题,则pthread_create会返回错误码12。

线程创建成功后,设置pthread_detach可以将线程状态更改为detach(分离)状态,正如上面所述,Linux中的线程有两种状态,joinable和detached,分别对应线程结束或退出时,线程创建的栈是否被析构,若为joinable,则不会自动析构,需要手动调用pthread_join()接口进行析构,若是detached,则可以确保资源的释放。线程创建后,调用这个借口将线程设置为detached状态,可以确保资源最终被释放。

int pthread_detach(pthread_t thread);

三、线程阻塞接口

接口定义:

int pthread_join(pthread_t thread, void** retval);

这个接口是将子线程合入主线程,主线程阻塞等待子线程结束,然后回收子线程资源。

四、获取线程ID方法

线程ID的获取可以用gettid方法:

pid_t tid;tid = syscall(SYS_gettid);

或者使用pthread_self()接口。但gettid和pthread_self()是有区别的。gettid获取的是内核中的线程ID,pthread_self获取的是POSIX thread ID。但gettid不可移植,只能用在LInux系统下,pthread_self()在Linux下与系统thread是一对一模型,可以认为一个gettid必然对应一个pthread_id,但二者之间不可相互转换。

五、线程休眠

线程休眠可以使用sleep()(或者usleep()等)或sched_yield(),但是这两个接口也有一些区别。sced_yield()可以使用另一个级别等于或高于当前线程的线程先运行,如果没有符合条件的线程,那么这个函数将会立刻返回然后继续执行当前线程的程序。而sleep则是等待一段时间后再等待CPU的调度,然后去获得CPU资源,在毫秒级别的usleep下,这种情况可能会导致休眠时间不准。

六、线程正常终止的方法

方法一:return从线程函数返回。

方法二:通过调用函数pthread_exit使线程退出。

方法三:线程可以被统一进程中的其他线程取消。

主线程中,main函数中调用了return或是调用了exit函数,则主线程退出,且整个线程也会终止,此时进程中所有的线程也将终止。

主线程中调用pthread_exit,则仅仅是主线程结束,进程不会结束。进程内的其它线程也不会结束,直到所有的线程结束,进程才会终止。

在任何一个线程中调用exit函数都会导致进程结束。进程一旦结束,所有进程中的线程都将结束。

#include <signal.h>int pthread_kill(pthread_t thread, int sig);

这个接口作用是向指定ID的线程发送sig信号,如果线程的代码内不作任何信号处理,则会按照信号的默认行为影响整个进程。假如发送了pthread_kill(threadid, SIGKILL),则杀死整个进程。

以上对Linux下常用的pthread线程库做了基本的介绍,也对一些线程机制做了简单的总结。实际使用时,我们可以根据需要调用各自功能的接口实现对多线程的控制。使用该库编译时要加-lpthread。

pthread线程库使用介绍相关推荐

  1. C/C++ pthread 线程库的封装

    经常没事写一些服务器压力测试的工具,如http,mysql,等.说到压力测试,首先想到的应该就是多线程,研究过一段时间的pthread,包括线程锁,在这里发一个自己写的Posix封装,可用于很多需要使 ...

  2. Linux系统编程36:多线程之线程控制之pthread线程库(线程创建,终止,等待和分离)

    文章目录 (1)POSIX线程库 (2)pthread_create--创建线程 A:关于Linux线程的再理解 B:线程ID及地址空间布局 (3)pthread_exit--线程终止 (4)pthr ...

  3. C++11学习笔记-----线程库std::thread

    在以前,要想在C++程序中使用线程,需要调用操作系统提供的线程库,比如linux下的<pthread.h>.但毕竟是底层的C函数库,没有什么抽象封装可言,仅仅透露着一种简单,暴力美 C++ ...

  4. 什么是线程?与进程又有什么区别,为什么要使用它,等对线程进行详细介绍

    一.什么是线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 进程: 划分空间,加载资源,静态的,资源单位 线程: 执行代码,执行能力,动态的,执行单位 进程只是用来把资源集中到 ...

  5. State Threads 回调终结者(ST线程库)

    本文转自: http://coolshell.cn/articles/12012.html 上回写了篇<一个"蝇量级"C语言协程库>,推荐了一下Protothreads ...

  6. [并发并行]_[线程模型]_[Pthread线程使用模型之一管道Pipeline]

    场景 1.经常在Windows, MacOSX 开发C多线程程序的时候, 经常需要和线程打交道, 如果开发人员的数量不多时, 同时掌握Win32和pthread线程 并不是容易的事情, 而且使用Win ...

  7. 在Ubuntu 14.04 64bit上编译并研究State Threads网络线程库源码

    State Threads是一个广受关注的高性能网络线程库,winlin在SRS中做了比较充分的应用,我很遗憾直到现在才精心研究它.下面是我的研究实录,以作备忘. 一.源码编译 下面是在Ubuntu ...

  8. linux 线程库在哪里,linux线程库

    简单地讲,进程是资源管理的最小单位,线程是程序执行的最小单位.一个进程至少要一个线程作为它的指令执行体,进程管理着资源(比如CPU,内存,文件等),而将线程分配到某个CPU上执行.一个进程当然可以拥有 ...

  9. 【C/C++多线程编程之四】终止pthread线程

    多线程编程之终止pthread线程 Pthread是 POSIX threads 的简称,是POSIX的线程标准.           终止线程似乎是多线程编程的最后一步,但绝不是本系列教材的结束.线 ...

最新文章

  1. kaggle竞赛--房价预测详细解读
  2. 安装python的redis模块
  3. 算法模板-对称性递归
  4. __getattribute__
  5. Eigen3的库使用
  6. 设计模式之单实例模式(Singleton)
  7. 神经网络结构可视化工具总结实践大全
  8. 在什么场合里你会用到消息队列?
  9. ecshop中$user对象
  10. 202206-2 寻宝!大冒险! CCF认证真题
  11. Mac配置iTem2主题、字体、颜色
  12. linux搭建云存储服务,CentOS 6.3搭建个人私有云存储ownCloud
  13. 2022年1月国产数据库排行榜:TiDB霸榜两年势头不减,openGauss与OceanBase分数大涨
  14. 推荐系统 - 基于标签的推荐算法
  15. 1323: 三角形判定
  16. MATLAB能进行拉氏变换吗,matlab拉氏反变换
  17. 论文笔记_SIGGRAPH2019会前课程:An Introduction to Physics-Based Animation_3
  18. Pandas Dataframe 每隔n行取1行
  19. 百问网七天物联网课程学习笔记——单片机开发模式
  20. Alibaba 官方微服务扛把子「SpringCloudAlibaba 全彩学习手册.PDF」,开源学习ing,

热门文章

  1. Go语言学习之打印九九乘法表
  2. map、set、multimap和multiset的使用【STL】
  3. DRILL(Sigcomm'17)阅读笔记
  4. 统计一篇英文文章中26 字母出现的概率
  5. J: Participate in E-sports [大数牛顿迭代判断是否是平方数]
  6. 【web】React-hooks
  7. Godaddy ssl续费更新问题总结
  8. Axure RP 9最新版软件及汉化包下载
  9. 【PX4-AutoPilot教程-1】PX4源码文件目录架构分析
  10. SDNU__1082.观妹种菊