一、进程和线程的关系
- 进程是程序执行和资源管理的最小单位
- 线程是存在于进程空间的,使用的是进程资源
- 线程是程序执行最小单位
- 线程 light process //轻量级的进程
- 进程 heavey process //重量级的进程
- 进程是分配资源和调度执行的基本单位。
- 分配资源 --- 进程 (获取系统系统资源)
- 调度执行 --- 线程 (侧重执行任务)
- 线程 -系统调度的最小单位
- 线程因为共享进程的资源避免了大量资源的开辟
- 线程的创建效率 高于进程创建效率
二、进程和线程的比较
1、进程中的资源
- pid
- ppid
- 打开的文件
- 虚拟地址空间
- code / data /bss
- 栈、堆
2、线程中资源
- tid
- 栈
- 信号
3、线程的优缺点
pthread 线程:
优点:
比多进程节省资源,可以共享变量。
概念:
线程是轻量级进程,一般是一个进程中的多个任务。
进程是系统中最小的资源分配单位.
线程是系统中最小的执行单位。
特征:
1、共享资源
2、效率高 30%
3、三方库: pthread clone posix
3.1 编写代码头文件: pthread.h
3.2 编译代码加载库: -lpthread library
libpthread.so
gcc 1.c -lpthread
缺点:
1,线程和进程相比,稳定性,稍微差些 //线程间的通信
2,线程的调试gdb,相对麻烦些。
4、线程与进程区别
资源:
线程比进程多了共享资源。
线程又具有部分私有资源。
进程间只有私有资源没有共享资源。
空间:
进程空间独立,不能直接通信。 //父进程 ---file -- 子进程 ---进程间通信
线程可以共享空间,可以直接通信。 // 通信方便,安全性较差,---线程间的通信(同步/互斥)
ipc(进程间通信)
三、线程的设计框架 (posix)
- 线程的创建 --- pthread_create
- 线程的执行
- 线程的退出
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
- 实现线程的操作
- 创建多线程
- 线程空间操作
- 线程资源回收
1、创建多线程:(NPTL)
int pthread_create(
pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine) (void *),
void *arg);
功能:
该函数可以创建指定的一个线程。
参数:
thread 线程id,需要实现定义并由该函数返回。
attr 线程属性,一般是NULL,表示默认属性。(可结合性+分离属性)
start_routine
指向指针函数的函数指针。
本质上是一个函数的名称即可。
称为
th 回调函数,是线程的执行空间。
{
}
arg 回调函数的参数,即参数3的指针函数参数。
返回值:
成功 0
失败 错误码
注意:
- 一次pthread_create执行只能创建一个线程。
- 每个进程至少有一个线程称为主线程。
- 主线程退出则所有创建的子线程都退出。
- 主线程必须有子线程同时运行才算多线程程序。
- 线程id是线程的唯一标识,是CPU维护的一组数字。(NPTL(tid) ---> linux(PID))
- pstree 查看系统中多线程的对应关系。
- 多个子线程可以执行同一回调函数。
四、有关线程
1.线程
轻量级的进程
线程不需要太多资源
{
线程tid
程序计数器
相关寄存器
栈的空间
}
线程 和 进程 关系
1.线程是存在进程中的
2.线程公用了进程的各个段 和相关资源(信号,打开文件)
线程 和 进程之间
进程 -- 重量级的进程 --- 成为 资源分配的基本单位
线程 -- 轻量级的进程 --- 成为 调度执行的最小单位
2.线程生命周期
创建 -- pthread_create
线程执行 -- 线程的执行函数 //(函数调用 --- 栈)
结束 --
3. pthread_exit();
主线程调用,表示主线程执行流结束,但是进程不销毁,
等所有子进程都结束时,进程才销毁
4、pthread_t pthread_self(void);
unsigned long int; %lu
功能:获取当前线程的线程id
参数:无
返回值:成功 返回当前线程的线程id
失败 -1;
五、线程的退出
1、 自行退出
==》 自杀 ==》 子线程自己退出
exit(1);
void pthread_exit(void *retval);
功能:子线程自行退出
参数: retval 线程退出时候的返回状态,临死遗言。
返回值:无
2、 强制退出
==》 他杀 ==》 主线程结束子线程
int pthread_cancel(pthread_t thread);
功能:请求结束一个线程
参数:thread 请求结束一个线程tid
返回值:成功 0
失败 -1;
六、线程的回收
1、线程的回收机制
====》不同与进程没有孤儿线程和僵尸线程。
====》主线程结束任意生成的子线程都会结束。
====》子线程的结束不会影响主线程的运行。
int pthread_join(pthread_t thread, void **retval);
功能:通过该函数可以将指定的线程资源回收,该函数具有
阻塞等待功能,如果指定的线程没有结束,则回收线程会阻塞。
参数:thread 要回收的子线程tid
retval 要回收的子线程返回值/状态。==》ptread_exit(值);
返回值:成功 0
失败 -1;
2、子线程的回收策略
- 如果预估子线程可以有限范围内结束则正常用pthread_join等待回收。
- 如果预估子线程可能休眠或者阻塞则等待一定时间后强制回收。
- 如果子线程已知必须长时间运行则,不再回收其资源。
3、线程的参数,返回值
1)、传参数
传整数 ===》int add(int a,int b); //a b 形参
add(x,y); //x y 实参
pthread_create(&tid,NULL,fun,x);
fun ==> void * fun(void * arg);
2)、传结构体
- 定义结构体类型
- 用结构体定义变量
- 向pthread_create传结构体变量
- 从fun子线程中获取结构体数据
3)、返回值
pthread_exit(0) ===> pthread_exit(9);
pthread_join(tid,NULL); ===> pthread_join(tid,?);
1、pthread_exit(?) ==>? = void * retval;
纯地址
2、pthread_join(tid,?) ==>? = void **retval;
地址的地址
原理:
子线程退出的时候,可以返回一个内存地址
改值所在的内存中可以存储任何数据,只要
地址存在,则数据都可以正常返回。
地址有三种:
0、栈区变量 错误,子线程结束该地址失效。
1、全局变量 失去意义,本质可以直接访问。
2、静态变量
3、堆区变量
主线程通过一个地址形式的变量来接受子进程
返回的地址变量就可以将该地址中的数据取到。
4、设置线程属性
int pthread_attr_init
int pthread_attr_destroy
int pthread_attr_setdetachstate
attached // 系
设置分离属性,目的线程消亡,自动回收空间。
attribute
int pthread_attr_init(pthread_attr_t *attr);
功能:
初始化一个attr的变量
参数:
attr,需要变量来接受初始值
返回:
0 成功,
非0 错误;
int pthread_attr_destroy(pthread_attr_t *attr);
功能:销毁attr变量。
attr,属性变量
返回:
0 成功,
非0 错误;
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
功能:把一个线程设置成相应的属性参数,attr,属性变量,有init函数初始化他。
detachstate:有2个可选值,
PTHREAD_CREATE_DETACHED:
设置分离属性。
第二种设置分离属性:
int pthread_detach(pthread_t thread);
功能:设置分离属性
参数:线程id号,填自己的id
线程退出清理函数:
void pthread_cleanup_push(void (*routine)(void *), void *arg);
功能:注册一个线程清理函数
参数:routine,线程清理函数的入口
arg,清理函数的参数。
返回值,无
void pthread_cleanup_pop(int execute);
功能:调用清理函数
execute,
非0 执行清理函数
0 ,不执行清理
返回值:无
触发方式:
1.pthread_cleanup_pop(非零值)
2.pthread_cleanup_pop(0) //pthread_exit() //退出动作会导致 触发
pthread_exit(NULL);
pthread_cleanup_pop(0);
3.pthread_cancel(); //被其它线程结束时
七、线程退出的清理函数
1.多线程程序设计
1).专门有个线程
init_system(); // ---很多资源的额申请 以及资源的初始化
2).负责执行处理的程序
do_exec();
3).关机
cleanup_resource(); //1. 专门一个线程 ,进行资源的释放。