2014年(2)
分类: LINUX
2014-03-28 16:12:41
原文地址:浅谈线程的一些问题(互斥锁,线程的实现方法,调度算法) 作者:我在乎的你
线程的学习:
线程使用于多处理调用机制。
一个进程中有许多的线程,但是至少有一个线程,一个线程的切换不会引起进程的切换,但是一个进程中的线程切换到另外一个进程的线程的时候,将会引起进程的切换。并且线程在切换的时候,仅需保存少量寄存器内容。
一般而言线程自己不拥有系统资源(但是还是会有一定的必不可少的资源),但是他可以放问隶属进程的资源。
每个进程中的各个线程都可以共享该进程的所有资源,这就首先表现在所有的线程都具有相同的地址空间。(进程的地址空间),这就意味着每个线程可以访问该地址的中的每一个虚地址。
多线程中的进程:
在多线程OS中,把线程当作独立的基本单位。此时所有的进程不再是一个可执行的实体,所有如此但是,所谓进程的执行,就是进程里面的某个线程的执行此时对进程的施加的状态,对线程仍然有作用,比如说一旦进程被挂起,里面的线程也就被挂起了。当某个进程被激活,属于该进程的所有的线程也就被激活了。
所以说多线程中的进程其实工作的还是里面的线程。
线程间的同步:
互斥锁(mutex):当一个线程去访问共享的数据段的时候,线程首先就会为他设置mutex,如果他是关闭的状态,则访问该数据段的线程就被阻塞。但是如果他现在是开锁状态,则线程就可以对数据段的所有东西进行读写。
但是为了防止线程被阻塞,系统提供了一个对mutex操作的Trylock命令。让他来检查是否是开锁和闭锁,只要是通过这个命令的返回状态码。
所谓的死锁就是一个线程要 访问临界区A ,但是线程还要访问临界资源B,但是临界资源的锁一直处于关闭状态,而此时的线程R正在访问临界资源B ,但是他还要访问临界区A。所以这样就导致了死锁的产生。
使用条件变量对这个问题的解决:
当线程进入临界区后,临界的锁就处于关闭状态,然后查找描述该资源的数据结构,看看他们时候在看看是否在忙碌,如果在忙碌状态,该线程就转为等待状态。并使该资源的锁处于打开状态。
线程同步的解决方法就是信号量机制:
(1)私有信号量:调用创建信号的函数来创建他,但是千万要注意,在使用结束时界的释放,一旦没有释放,一旦没有释放,而这个线程结束,这个信号量就一直存在,也不能被下一个申请的线程所使用,容易造成内存泄露。
(2)公有信号量:他是一个名字供所有的进程使用。即使你没有释放,os 也会将该信号量的空间释放。所以说公有信号量是一种比较安全的同步机制。
线程的实现方式:
(1)内核支持线程:线程的所有操作都与内核有关。,内核根据线程块来控制线程。当一个进程中的线程被阻塞,内核通过调度来执行这个进程中的其他线程。但是切换的时候,开销较大。当一个线程切换到另一个线程,这个线程先要切换到内核态,在有内核觉得他的后续工作。(调度以线程为单位)
(2)用户级线程:线程切换,创建。。都与内核无关。但是设置用户级线程的系统,其调度都是与进程有关的。例如有进程A和进程B,进程A里面有一个线程,进程B里面有100个线程,但是内核对进程处理都是一样的,都是轮转调度算法,给每个进程分配一定的时间片,这时候进程A的处理速度就是进程B的100倍。这种方法实现的线程,在线程的切换等等,开销要小。当一个线程执行系统调用的时候,被阻塞,这个进程中的所有的线程都被阻塞。
线程的实现过程:
内核支持线程:
创建进程的时候就内核就会为进程一个任务数据区PATA,包含了若干个线程TCB空间。TCB (关于进程的创建,撤销...)当创建一个线程就进程就会其分配一个TCB 空间,但是如果一旦PATA 的空间被分配完了,而进程所创建的线程还在系统的规定范围里面。系统就会为其分配相应的TCB 空间。
如果线程结束,系统并不会立即收回该线程的资源,而是等到系统在创建新的进程的时候,才会回收他的资源。
用户级线程:
(1)运行时系统 :本质是处理线程函数的集合。这些函数停驻在用户的空间。(内核与用户级线程之间的API)。
(2)内核控制线程:用户级线程链接到这种线程上就具有内核支持线程的属性。
而这种线程可以做成一个线程池。但是如果一个进程中的这种线程都被阻塞,这个进程中的线程还可以执行,只是无法与内核进行通信。
调度算法的总结:
A: 先来先服务算法(FCFS):
这个方法有利于长作业,但是不利于短作业。
B:进程优先算法:
根据进程运行时间的长短决定,虽然提高了系统的吞吐量但是对于运行时间长的,很难被执行。
C:优先权调度算法:
(1)非抢占式的优先权:一旦系统把处理机分配给优先级高的进程,就要等到这个进程结束或者自动放弃,后来优先级高的进程才能被处理。但是这样也不利于时间紧迫的进程。
(2)抢占式优先权:根据优先权的高低来决定处理机当前要处理的任务,但是这样会加剧进程间切换的频繁。并且对每一个进入对列的进程都要判断他的优先级和当前处理的进程的优先权的大小。
优先权的类型也决定这个算法:
(1)静态优先权:顾名思义就是在进程的执行过程中,进程的优先权不随时间的变化,就是在创建进程的时候所确定的优先权。对于优先权的数值的意义由操作系统所确定。
(2)动态优先权:在创建进程的时候所确定的优先权会随着进程的推进和其等待的时间的增加而不断的发生改变。
D : 高响应比优先调度算法:
是包含了A,B,C三种方法的折中。
E:基于时间片的轮换调度算法:
如果当前任务执行的时间或者等待的时间大于时间片所规定的时间。计时器发送时钟中断请求。该任务就会重新回到就绪状态。
但是时间片的大小是又大多数进程都可以完成任务所确定的,不能太长,如果太长就和A算法没有区别,如果太短,频繁的发送中断请求,进程上下文的切换就会增加系统的开销。
F:多极反馈队列调度算法:
这种算法是 好几种算法的一个结合;
(1)设置好几个队列,并且对列1的优先级最高,其余的依次递减。但是系统所给队列1中的进程的时间片最短,其余的依次递增。
(2)系统先处理队列1,按照FCFS原则进行处理。
(3)如果系统在处理队列i的时候,这时候有新的进程进入到队列i前面的队列,这时候,当前的处理任务被进的进程所抢占。等到处理完新的进程,重新再来处理队列i中的任务。