线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。
一个线程包含以下内容:
- 一个指向当前被执行指令的指令指针;
- 一个栈;
- 一个寄存器值的集合,定义了一部分描述正在执行线程的处理器状态的值;
- 一个私有的数据区;
所有这些元素都归于线程执行上下文的名下。处在同一个进程中的所有线程都可以访问该进程所包含的地址空间,当然也包含存储在该空间中的所有资源。
为什么有了进程的概念后,还要再引入线程呢
首先:
在许多应用中会同时发生多种活动,某些活动会随着时间的推移被阻塞,通过将这些应用程序分解成可以准备并行运行的多个顺序线程,程序 ,设计模型会变得简单起来。
这里可以说加入了一个新的元素:并行实体共享同一个地址空间和所有可用数据的能力对于某些应用而言,这种能力是必须的,而这正是多进程模型(它们具有不同的地址空间)无法表达的。
第二个:
由于线程比进程更轻量级,所以它们更容易(更快)创建和撤销。在一般情况下,创建一个线程比创建一个进程要快上10~100倍。在有大量线程需要动态和快速修改时,具有这一特性是非常重要的。
第三个:
需要多线程的理由是关于性能方面的,若多个线程都是CPU密集型的,那么多线程并不能很明显地体现出它的性能提升,但是在一些需要大量1/0处理和大量计算的情况下,拥有多线程允许这些活动彼此重叠进行,对程序性能的提升是非常明显的。
最后:
在多CPU系统中,多线程是有益的,在这样的系统中,可以真正实现物理上的多线程并行运行。
线程概念试图实现的是:
共享一组资源的多个线程的执行能力,以便这些线程可以为完成某项任务而共同工作。
进程用于将资源集中在一起,而线程则是在CPU上被调度的实体。
1.多线程的优点:
何时使用多线程技术?何时避免用它?是我们需要掌握的重要课题。多线程技术是一把双刃剑,在使用时需要充分考虑它的优缺点。
多线程处理可以同时运行多个线程。由于多线程应用程序将程序划分成多个独立的任务,因此可以在以下方面显著提高性能。
- 多线程技术使程序的响应速度更快,因为用户界面可以在进行其他工作的同时一直处于活动状态。
- 当前没有进行处理的任务时可以将处理器时间让给其他任务。
- 占用大量处理时间的任务可以定期将处理器时间让给其他任务。
- 可以随时停止任务。
- 可以分别设置各个任务的优先级以优化性能。
是否需要创建多个线程取决于各种因素,在以下情况下最适合采用多线程处理:
- 耗时或大量占用处理器的任务阻塞用户界面操作。
- 各个任务必须等待外部资源(如远程文件或Internet连接)。
2.多线程的缺点:
同样,多线程也存在许多缺点,在考虑多线程时需要进行充分的考虑。多线程的主要缺点包括:
- 等候使用共享资源时会使程序的运行速度变慢,这些共享资源主要是独占性的资源,,如打印机等。
- 对线程进行管理要求额外的CPU开销。线程的使用会给系统带来上下文切换的额外负担,当这种负担超过一定程度时,多线程的特点主要表现在其缺点上,比如用独立的线程来更新数组内每个元素。
- 线程的死锁。即较长时间的等待或资源竞争,以及死锁等多线程症状。
- 对公有变量的同时读或写。当多个线程需要对公有变量进行写操作时,后一个线程往往会修改掉前一个线程存放的数据,从而使前一个线程的参数被修改;另外当公用变量的读写操作是非原子性时,在不同的机器上,中断时间的不确定性,会导致数据在一个线程内的操作产生错误,从而产生莫名其妙的错误,而这种错误是程序员无法预知的。
注释:
上下文
上下文是从英文context翻译过来,指的是一种环境。相对于进程而言,就是进程执行时的环境;
具体来说就是各个变量和数据,包括所有的寄存器变量、进程打开的文件、内存信息等。
在gcc test.c
编译程序时出现“undefined reference to ‘pthread_create’”,所有关于线程的函数都会有此错误,导致无法编译通过。
问题的原因:pthread不是Linux下的默认的库,也就是在链接的时候,无法找到phread库中哥函数的入口地址,于是链接会失败。
解决:在gcc编译的时候,附加要加 -lpthread参数即可解决。