线程是什么
在早期的计算机中并没有线程这个概念,早期CUP的最小分配资源单位和最小调度单位都是线程,然而随着计算机的发展,进程在产生,销毁,切换过程中的时间和空间的浪费被越来越多的人注意到,所以在上世纪80年代,计算机领域提出了轻量级进程(线程)的概念,这种轻量级进程一经提出,便在Windows等图形界面操作系统被应用,因为这种轻量级进程能很好地解决Windows中进程太多,CPU调度过于密集的问题.
线程与进程的区别
- 进程是CPU分配资源的最小单位,线程是CPU调度的最小单元;
- 线程是一个轻量级进程,一个进程可以产生多个线程,一个线程不能产生进程.
- 在进程中创建的线程被称为一个线程组,这些线程分配进程的大部分内存资源(全局区,代码区,堆…);
- 在Linux中线程是后期被提出来的,但在系统调用中没有专门用来操作线程的接口,线程的操作被封装为一个动态库,但操作系统提供进程操作接口.
线程的特性
优点:
- 线程间通信非常灵活,因为,在同一个线程组中的线程共享当前物理内存中的大部分资源,所以当前内存中的大部分资源可以被多个线程访问.
- 线程中的产生,销毁,切换等操作相比进程成本更低,因为线程作为一个轻量级进程,产生时不需要重新生成虚拟内存,同样销毁时也更轻便,在同一个线程组之间进行切换时不需要重新映到射物理内存,所以切换更加快速.
缺点:
- 多线程编程时线程安全很难保证, 因为同一个线程组的线程共享大部分内存资源,所以对内存中的大部分数据,所有线程都有权利访问和修改,数据安全问题很难保证.
- 对于很多系统调用,都是对进程产生效果,例如_exit();一个线程组中的任意一个线程调用这个函数都会导致整个线程组的销毁.
同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈,自己的寄存器环境,自己的线程本地存储。
线程的相关操作
由于线程的相关操作被封装为一个库,所以多线程程序在编译时需要链接pthread库.
头文件pthread.h
- 创建线程
int pthread_creat (pthread_t * id,pthread_attr_t * attr,void * ( * thread_routine)(void* arg),void* arg);
线程创建函数返回值为0表示创建成功,非0为错误编号.
第一个参数为线程id,同样也是线程调用栈的指针,是用来获取线程id的.
第二个参数为创建时需要添加的一些属性,先不做过多介绍,可以为NULL.
第三个参数为线程的入口函数,是一个返回值为void*,参数为void*的函数指针
第四个参数是入口函数中要传入的参数. - 线程的退出
(1)线程入口函数中return.
(2)在本线程中调用void pthread_exit(void* retval),参数为线程退出的返回值.
(3)在当前线程组中的任意位置调用int ptherad_cancel(pthread_t tid),指定退出tid线程.
注:在线程组中任意位置调用_exit();都会导致线程组的销毁 - 线程的退出处理
线程在退出后,资源不会被回收,而是要调用接口等待回收或设置分离属性
(1)int pthread_join(pthread_t tid,void ** retval);等待回收线程资源
为阻塞接口,第一个参数为需要回收的线程id,第二个参数为线程退出返回值.
注:在未设置分离属性的前提下,线程退出后一定要进行回收,否则会造成资源的丢失.
(2)int pthread_detach(pthread_t tid);设置分离属性,线程退出后,自动释放资源,为非阻塞接口
代价为丢失线程退出的返回值.
- 本文为本人学习笔记,如有错误之处,还望指出