关于线程实现的学习(2)用户级线程库

这里有篇长长的文章,还没看,应该还不错吧,尤其原作者的主页值得一看
http://www.frontfree.net/view/article_768_page1.html

一.线程模型
用户线程和内核线程的对应关系有一对一,多对多,多对一。
用户线程的好处的高效调度,缺点是不能在多处理器上高效,一个线程的系统调用阻塞
导致整个线程组阻塞。
内核线程的优缺与用户线程刚好相反。
多对多模型是两者的折中。

二一个简单用户级线程库的实现
看看task结构的庞大吧,线程切换也要很多overhead,那么转向fiber吧...也许它是个
用户线程,假如你有几千个线程在跑....

1首先需要定义一个用户级线程的数据表示:
有:
线程号
堆栈指针
积存器集合
也就这些了

2关于stack
2004年10月14日17:14:11补充
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=linuxK&Number=392651&page=0&view=collapsed&sb=5&o=31&fpart=all&vc=1

http://www.linuxforum.net/forum/showflat.php?Cat=&Board=linuxK&Number=408792&page=1&view=collapsed&sb=5&o=7&fpart=

在函数调用时stack是最常打交道的东西了。

(1)stack是如何改变的呢?
a在X86中有push/pop指令
push=>sp-4/mem[sp]=内容
pop=>get mem[sp]/sp+4
call=>push eip/eip=dest function
ret=>pop eip
从这里可以看出X86上对应于ARM的满栈递减。
b mips里有SGI规定的函数调用规则,见http://www.cnblogs.com/mips
c arm 里有APCS
(2)堆栈中frame的概念

void function(int a)
{
    int local = a;
}为例

在反汇编的代码里看到
pushl %ebp
movl %esp, %ebp
subl $4, %esp
这样的一段代码是什么意思呢,在x86中函数堆栈是通过EBP寻址的(也可通过SP寻址,但需OMIT FRAME)。其中第3句把堆栈划分了
一下。
调用通过call指令完成,在这之前还需要由调用者把参数压入堆栈。
于是,这时堆栈的排布为:

内存地址高的方向
-----------------
a
-----------------
return ip address
-----------------
原来的ebp
-----------------
local<===========被subl $4,%esp划分出来的。
-----------------
内存地址低的方向

那么函数中local = a;如何来汇编呢。
就是如下两句
movl 8(%ebp), %eax
movl %eax, -4(%ebp)
可以清楚的看到通过ebp把堆栈划分为上下两部分,一部分是传如参数+,一部分是局部变量-。

3关于线程切换
需要保存和恢复的积存器组为
除了IP外
X86:
ebx,esi,edi,ebp,esp
MIPS:
惊诧于如此多的积存器需要保存!
$16-$31,还有浮点积存器f20-f30,这部分不敢肯定。


我们想实现的目标
1创建两个线程2ctrl-c可在这两个线程中切换

碰巧看到的:POWERPC的汇编
http://www-900.ibm.com/developerWorks/cn/linux/hardware/ppc/assembly/index.shtml

该考虑的一些问题:
1抢占
有中断来临时,重新调度就绪队列

2线程切换的时机:
在线程库中涉及到线程调度的代码应该都是禁止中断的。也就是抢占的时机

3信号量/channel的支持
值得注意的是信号量如果调度不好会有饿死的情况发生-总是只有一个线程得到信号量进入临界
区。
channel则是一个同步channel,也就是线程间消息的同步。

4实时性能
也就是禁止中断的窗口大小。

5一些微妙的地方。
对于不同的体系,在线程切换时候要保存的范围也不同。应该尽量减小这个范围,
而这个范围又是和实时性能(禁止中断的窗口)互相排斥的。

///////////////////////////// 中间插两句///////////////////////////////////////////////////////////
又看到了一篇
http://www.21ic.com/new_info/news/files/news/200381803435.asp
写的好的。
实时==确定时间
非实时性来源:据说是因为非RTOS的系统对TASK队列进行搜索,由于队列的
长度的不确定性。
抢占==基于事件的,任意时间可中断运行来进行调度。而不向LINUX以前2.4
版本只有在非内核态下才是可抢占的。从这个意义来说,本文的调度系统也
只是部分可抢占的。

一般RTOS需要提供的服务:
1)任务调度
2)共享资源管理-信号量
3)进程间通讯-消息机制fifo,message
4)可选的内存管理,比如动态内存分配

一般RTOS容易出现的问题:
1)task饿死 - 非时间片轮转
2)优先级倒置
///////////////////////////////////////////////////////////////////////////////////////////

未完...

posted on 2004-07-28 09:24  embed  阅读(1425)  评论(0编辑  收藏  举报

导航