线程(TCB)的概念
1. 线程是一个进程内部的控制序列
2. 一切进程至少都有一个执行线程
进程和线程:
1. 线程是在进程内部运行的执行流(线程在进程的地址空间内运行)
2. 线程执行粒度更细
3. 线程之间大部分资源是共享的(但也有私有的:线程拥有独立的上下文数据、有自己的私有栈结构)
进程的多个线程共享:地址空间、代码数据、文件描述符、当前工作目录、用户id和组id
线程出错相当于进程出错,线程内资源共享,一个线程出错其它也会错;当进程程序运行时,一个进程出错不会形象其它进程,进程具有独立性、进程更安全、线程更方便
线程的优点
创建一个新线程的代价要⽐创建⼀个新进程小得多
与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多
线程占⽤的资源要比进程少很多
能充分利⽤多处理器的可并行数量
在等待慢速I/O操作结束的同时,程序可执⾏其他的计算任务
计算密集型应⽤,为了能在多处理器系统上运行,将计算分解到多个线程中实现
I/O密集型应⽤,为了提⾼性能,将I/O操作重叠。线程可以同时等待不同的I/O操作
线程的缺点
1.性能损失
一个很少被外部事件阻塞的计算密集型线程往往无法与共它线程共享同一个处理器。如果计算密集型线程的数量⽐可⽤的处理器多,那么可能会有较⼤的性能损失,这⾥里的性能损失指的是增加了额外的同步和调度开销,⽽可用的资源不变。
2.健壮性降低
编写多线程需要更全面更深⼊的考虑,在⼀个多线程程序⾥,因时间分配上的细微偏差或者因共享了不该共享的变量而造成不良影响的可能性是很大的,换句话说线程之间是缺乏保护的。
3.缺乏访问控制
进程是访问控制的基本粒度,在一个线程中调⽤某些OS函数会对整个进程造成影响。
4.程难度提⾼高
编写与调试一个多线程程序比单线程程序困难得多
创建线程
功能:创建⼀一个新的线程
原型
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*star
t_routine)(void*), void *arg);
参数
thread:返回线程ID
attr:设置线程的属性,attr为NULL表⽰示使⽤用默认属性
start_routine:是个函数地址,线程启动后要执⾏行的函数
arg:传给线程启动函数的参数
返回值:成功返回0;失败返回错误码
线程退出2种:跑完正确、跑完错误
pthread_t pthread_self(void);
对于Linux目前实现的NPTL实现而言,pthread_t类型的线程ID,本质就是一个进程地址空间上的 一个地址。
线程终止
如果只终止某个线程而不终止整个进程;
- 从非主线程函数return
- 线程可以调用pthread_exit终止自己
- 一个线程可以调用pthread_cancel终止同一进程中的另一个线程
pthread_exit函数:
功能:线程终⽌止
原型
void pthread_exit(void *value_ptr);
参数
value_ptr:value_ptr不要指向⼀一个局部变量。
返回值:⽆无返回值,跟进程⼀一样,线程结束的时候⽆无法返回到它的调⽤用者(⾃自⾝身)
pthread_cancel函数:
功能:取消⼀一个执⾏行中的线程
原型
int pthread_cancel(pthread_t thread);
参数
thread:线程ID
返回值:成功返回0;失败返回错误码
线程等待与分离
线程以阻塞方式进行等待
线程默认为可结合的,必须等待,否则内存泄漏
一个线程出现异常,会连累进程本身