- 論壇徽章:
- 0
|
NetBSD 5.0 的線程模型由M:N改成了1:1,關(guān)于M:N的實(shí)現(xiàn),有一篇論文可以看看:http://www.mit.edu/people/nathanw/usenix/freenix-sa/freenix-sa.html。
多進(jìn)程的操作系統(tǒng)中線程的實(shí)現(xiàn)一般有這幾種:N:1,M:N,1:1,這幾種中可能M:N是最復(fù)雜的。因?yàn)榫程的實(shí)現(xiàn)可以有很多種方式,可以在用戶態(tài)實(shí)現(xiàn),并且調(diào)度算法也在用戶態(tài),這樣實(shí)現(xiàn)的好處是實(shí)現(xiàn)起來簡單,不用動內(nèi)核的代碼,這種就是N:1,這樣可以在本來只支持進(jìn)程的系統(tǒng)上實(shí)現(xiàn)線程以滿足多任務(wù)需求,但這樣即使一個進(jìn)程中有多個線程,而且有多個CPU,同一進(jìn)程的不同線程也不能并行的跑,因?yàn)閮?nèi)核是以進(jìn)程為調(diào)度對象的,不能充分利用SMP和多核的性能,所以現(xiàn)在的操作系統(tǒng)中已經(jīng)很少有這種實(shí)現(xiàn)了,OpenBSD 早期就是這種實(shí)現(xiàn),雖然現(xiàn)在OpenBSD還是不支持內(nèi)核線程,但他對專門對用戶態(tài)的線程支持做了一些改動,現(xiàn)在OpenBSD是可以支持多線程并行跑的。也可以再內(nèi)核態(tài)實(shí)現(xiàn),即內(nèi)核的調(diào)度單位就是線程,現(xiàn)在的FreeBSD,NetBSD,Solaris 就是這樣的實(shí)現(xiàn)。當(dāng)內(nèi)核調(diào)度單位也是線程的時候,就出現(xiàn)一個問題:調(diào)度算法是在用戶態(tài),還是放到內(nèi)核?這樣就出現(xiàn)了M:N和1:1的問題。M:N其實(shí)理論上來講是一種完美的線程模型,這種模型也有很多種實(shí)現(xiàn),最早的M:N的實(shí)現(xiàn)是由Sun在Solaris上做出來的,那時叫不叫Solaris我不清楚啊,有興趣的可以去查一下,后來NetBSD和FreeBSD也實(shí)現(xiàn)了這種模型,但實(shí)現(xiàn)后可能發(fā)現(xiàn)維護(hù)上帶來的困難比由此帶來的性能上的提升大的多,或者好像是現(xiàn)在的任務(wù)跟本就用不了這么強(qiáng)悍的性能,Sun后來放棄了這種模型,改為實(shí)現(xiàn)較為簡單的1:1的模型,具體為什么Sun會放棄M:N可以參看一本叫《Solaris內(nèi)核結(jié)構(gòu)》的書,里面好像有詳細(xì)說為什么,不過我也忘了是在哪兒看的了哈。NetBSD在5.0,即當(dāng)前最新版中改成了1:1的模型,F(xiàn)reeBSD在也在剛實(shí)現(xiàn)了M:N的模型后沒多久就改成了1:1。其實(shí)關(guān)于Unix的一些新的feature,很多都是有Sun先實(shí)現(xiàn),然后社區(qū)才參看Sun的實(shí)現(xiàn)來實(shí)現(xiàn)。
說了這么多該說說代碼了,NetBSD中的內(nèi)核線程叫l(wèi)wp(light weight process),這個和Solaris的叫法是一樣的。應(yīng)用庫叫l(wèi)ibpthread分別位于src/sys/kern下和src/lib/libpthread下,他的pthread的大部分功能都直接映射給內(nèi)核了,調(diào)度由內(nèi)核完成。5.0里的pthread庫應(yīng)該是重寫了的,很簡單,大部分都直接轉(zhuǎn)到以_lwp_開頭的系統(tǒng)調(diào)用上去了,比如pthread_create()就最終轉(zhuǎn)到_lwp_create()上去了,當(dāng)然pthread_create()還有其他的工作要做。其實(shí)看代碼主要關(guān)注這幾個方面:fork(),lwp的結(jié)構(gòu)以及線程上下文切換。
fork()在創(chuàng)建了進(jìn)程之后會創(chuàng)建一個線程,這個線程就是這個進(jìn)程內(nèi)核的調(diào)度單位,當(dāng)然如果這個進(jìn)程同時還創(chuàng)建了很多線程,那么這些線程就是調(diào)度單位,內(nèi)核可以同時在多個CPU上跑同一個進(jìn)程的多個線程。lwp的結(jié)構(gòu)在src/sys/sys/lwp.h中,對lwp的操作的函數(shù)主要在src/sys/kern/kern_lwp.c中實(shí)現(xiàn)。上下文切換的實(shí)現(xiàn)在sys/kern/kern_synch.c中,函數(shù)名叫mi_switch(),在這個函數(shù)中如果線程發(fā)生了變化,會置一個標(biāo)志位,在從kernel返回到userspace的時候會檢查,如果要返回的線程和當(dāng)前cpu的地址空間不一樣,就進(jìn)行地址空間的切換,否則不會發(fā)生地址空間的切換,因?yàn)榈刂房臻g切換開銷很大。相關(guān)的函數(shù)是pmap_deactivate(),pmap_activate()和pmap_load(),在前兩個函數(shù)中置標(biāo)志位,真正的切換發(fā)生在pmap_load()中。
和線程相關(guān)的還有同步問題,線程的調(diào)度算法問題等,后面會接著介紹。
本文來自ChinaUnix博客,如果查看原文請點(diǎn):http://blog.chinaunix.net/u/16553/showart_2025966.html |
|