pthread线程库使用介绍
多线程的开发和应用在平时的项目中使用非常频繁。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线程库使用介绍相关推荐
- C/C++ pthread 线程库的封装
经常没事写一些服务器压力测试的工具,如http,mysql,等.说到压力测试,首先想到的应该就是多线程,研究过一段时间的pthread,包括线程锁,在这里发一个自己写的Posix封装,可用于很多需要使 ...
- Linux系统编程36:多线程之线程控制之pthread线程库(线程创建,终止,等待和分离)
文章目录 (1)POSIX线程库 (2)pthread_create--创建线程 A:关于Linux线程的再理解 B:线程ID及地址空间布局 (3)pthread_exit--线程终止 (4)pthr ...
- C++11学习笔记-----线程库std::thread
在以前,要想在C++程序中使用线程,需要调用操作系统提供的线程库,比如linux下的<pthread.h>.但毕竟是底层的C函数库,没有什么抽象封装可言,仅仅透露着一种简单,暴力美 C++ ...
- 什么是线程?与进程又有什么区别,为什么要使用它,等对线程进行详细介绍
一.什么是线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 进程: 划分空间,加载资源,静态的,资源单位 线程: 执行代码,执行能力,动态的,执行单位 进程只是用来把资源集中到 ...
- State Threads 回调终结者(ST线程库)
本文转自: http://coolshell.cn/articles/12012.html 上回写了篇<一个"蝇量级"C语言协程库>,推荐了一下Protothreads ...
- [并发并行]_[线程模型]_[Pthread线程使用模型之一管道Pipeline]
场景 1.经常在Windows, MacOSX 开发C多线程程序的时候, 经常需要和线程打交道, 如果开发人员的数量不多时, 同时掌握Win32和pthread线程 并不是容易的事情, 而且使用Win ...
- 在Ubuntu 14.04 64bit上编译并研究State Threads网络线程库源码
State Threads是一个广受关注的高性能网络线程库,winlin在SRS中做了比较充分的应用,我很遗憾直到现在才精心研究它.下面是我的研究实录,以作备忘. 一.源码编译 下面是在Ubuntu ...
- linux 线程库在哪里,linux线程库
简单地讲,进程是资源管理的最小单位,线程是程序执行的最小单位.一个进程至少要一个线程作为它的指令执行体,进程管理着资源(比如CPU,内存,文件等),而将线程分配到某个CPU上执行.一个进程当然可以拥有 ...
- 【C/C++多线程编程之四】终止pthread线程
多线程编程之终止pthread线程 Pthread是 POSIX threads 的简称,是POSIX的线程标准. 终止线程似乎是多线程编程的最后一步,但绝不是本系列教材的结束.线 ...
最新文章
- kaggle竞赛--房价预测详细解读
- 安装python的redis模块
- 算法模板-对称性递归
- __getattribute__
- Eigen3的库使用
- 设计模式之单实例模式(Singleton)
- 神经网络结构可视化工具总结实践大全
- 在什么场合里你会用到消息队列?
- ecshop中$user对象
- 202206-2 寻宝!大冒险! CCF认证真题
- Mac配置iTem2主题、字体、颜色
- linux搭建云存储服务,CentOS 6.3搭建个人私有云存储ownCloud
- 2022年1月国产数据库排行榜:TiDB霸榜两年势头不减,openGauss与OceanBase分数大涨
- 推荐系统 - 基于标签的推荐算法
- 1323: 三角形判定
- MATLAB能进行拉氏变换吗,matlab拉氏反变换
- 论文笔记_SIGGRAPH2019会前课程:An Introduction to Physics-Based Animation_3
- Pandas Dataframe 每隔n行取1行
- 百问网七天物联网课程学习笔记——单片机开发模式
- Alibaba 官方微服务扛把子「SpringCloudAlibaba 全彩学习手册.PDF」,开源学习ing,