- 线程概念
- 进程中的主线程在执行代码,执行流.
- 线程只是在进程虚拟地址空间中拥有相对独立的一块空间,线程包含cpu现场,但是线程只是进程中的一个执行流,进程是资源分配的基本单位,线程是调度的基本单位,每个线程在进程虚拟地址空间中拥有独立的栈空间,线程有自己的独立栈空间且共享数据,,,由于线程没有独立的地址空间.进程比线程安全的原因是每个进程由独立的虚拟地址空间,具有独立性
- 同一个进程中线程的切换不会引起进程的切换,由一个进程的线程切换到另一个线程的进程时才引起进程的切换
- 其中有一个主线程来调用本进程中的其他线程。我们看到的进程的切换,切换的也是不同进程的主线程下.多线程可以让同一个进程同时并发处理多个任务,相当于扩展了进程的功能。
- 线程的切换分为同一个进程里的线程切换,共享数据不用从CPU中剥离....不同进程的线程切换:就要把线程全部剥离CPU
- 程序员创建的线程不是从main函数开始执行的 程序员创建的线程叫工作线程,main函数开始的叫主线程
- 线程是轻量级进程,linux操作系统没有线程
- 进程里理解的是,一个进程一个task-struct结构体,其实一个task_struct结构体本来是一个轻量级进程,大小也算个进程把.为什么在进程那说他是进程呢,因为在进程里没有创建线程,只有一个主线程.所以才称为进程,fork创建的是一个子进程,克隆多个线程?tgid是轻量级进程组ID
- 线程的共享与独有
- 创建一个线程是在共享区给线程分配一个独有的空间,空间里有一个调用栈,在这个调用栈里执行代码可以不被其他线程影响.线程在这片区域创建自己的栈帧销毁自己的栈帧,多个线程就不混乱了.
- 线程独有内容放在的共享内存这块区域,独有的有调用栈,寄存器,线程ID,errno(错误码),信号屏蔽字(阻塞位图),调度优先级
- 多线程有一部分数据是共享的:文件描述符,用户id,用户组id,信号处理方式,当前进程的工作目录
- 优缺点
- 多线程有多个执行流,合理使用可以提高程序运行效率,多线程程序的线程切换比多进程程序快,付出的代价小(有些可以共享的数据在切换时就不用从cpu中被剥离出来,就省时间了),充分发挥多核cpu并行的优势(对于运算密集型的程序,可进行拆分,最后整合...I/O密集型程序,也可以拆分) 多个执行流可以在同一时刻跑多种类型的代码,例如一个在文件里读数据的程序要把文件读完要读10秒,没有多线程的时候等执行到这一步就得等10秒,如果有多线程就可以让一个线程运行代码,一个线程提前去读出来,就不用等了.
- 缺点:代码编写难度更加高,代码的稳定性要求更高,一个线程崩溃,导致整个进程退出.线程的数量不是越多越好(多到一定程度,光线程切换可能都比一个线程多)线程的多少也没有一个确定值,要基于机器性能,要经过测试得来.缺乏访问控制,可能导致程序产生二义性.
- 线程控制
- 线程创建:
- 参数:
- thread:获取线程标识符(地址),本质上就是线程独有空间的首地址
- attr:线程的属性信息,一般填写NULL,采用默认线程属性,属性里主要的是调用栈的大小,分离属性,调度策略,调度优先级等.
- start_routine:函数指针,线程执行的入口函数(线程开始执行起来的时候,从该函数开始运行,切记不是从main函数运行的)
- arg:给线程入口函数传递的参数,也可以不传参...传参不要传临时变量
- 代码:
- 代码执行后什么结构也没有:因为主线程和工作线程都要被操作系统调度,主线程退出后工作线程也就没有了...main函数加一个sleep(),让主线程等一下,等工作线程执行完.
- 工作线程把他的代码执行完就退出了,,不是主线程退出工作线程才退出
- 查看线程的命令
- top动态查看操作系统的资源...top -H -p [进程号]动态查看某一个进程的线程
- pstack [进程号],查看调用堆栈
- 就是说要执行到自己定义的函数那,还得一段时间.如果还没执行到自己定义的函数主线程退出,那么工作线程的代码也不会执行
- top动态查看操作系统的资源...top -H -p [进程号]动态查看某一个进程的线程
- 线程终止:
- 谁调用谁退出,立即退出,retval:线程退出时,传递给等待线程的退出信息
- 退出线程标识符对应的线程,也能终止自己
- 获取自己的线程标识符
- 主线程终止自己,工作线程死循环中,主线程变成了僵尸进程...如果工作线程退出主线程也就从僵尸线程退出了
- 谁调用谁退出,立即退出,retval:线程退出时,传递给等待线程的退出信息
- 线程等待
- 线程被创建出来的时候默认属性是joinable属性,依赖其他线程回收资源(主要是退出线程使用到的共享区当中的内存),是一个阻塞调用接口(解决主线程提前退出的情况,入主线程阻塞等待)
- thread:线程标识符;retval:退出线程的退出信息,第一种:线程入口函数执行完毕,线程退出,就是入口函数的返回值.第二种:pthread_exit退出的,就是这个pthread_exit的参数,第三种:cancel函数退出的,就是一个宏:PTHREAD_CANCELED
- 主线程等待工作线程,阻塞等待,工作线程退出后主线程才能继续开始运行.
- 线程被创建出来的时候默认属性是joinable属性,依赖其他线程回收资源(主要是退出线程使用到的共享区当中的内存),是一个阻塞调用接口(解决主线程提前退出的情况,入主线程阻塞等待)
- 线程分离
- 线程的分离属性,一旦线程设置了分离属性,线程退出后不需要任何线程回收他的退出信息,操作系统进行回收;自己给自己设置或者别人设置都行
- 线程的分离属性,一旦线程设置了分离属性,线程退出后不需要任何线程回收他的退出信息,操作系统进行回收;自己给自己设置或者别人设置都行
- 线程创建:
linux-->多线程
最新推荐文章于 2024-06-03 19:08:43 发布