• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            cc

              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              38 隨筆 :: 14 文章 :: 21 評論 :: 0 Trackbacks

            在.NET多線程編程這個(gè)系列我們講一起來探討多線程編程的各個(gè)方面。首先我將在本篇文章的開始向大家介紹多線程的有關(guān)概念以及多線程編程的基礎(chǔ)知識(shí);在接下來的文章中,我將逐一講述。NET平臺(tái)上多線程編程的知識(shí),諸如System.Threading命名空間的重要類以及方法,并就一些例子程序來作說明。

            引言

              早期的計(jì)算硬件十分復(fù)雜,但是操作系統(tǒng)執(zhí)行的功能確十分的簡單。那個(gè)時(shí)候的操作系統(tǒng)在任一時(shí)間點(diǎn)只能執(zhí)行一個(gè)任務(wù),也就是同一時(shí)間只能執(zhí)行一個(gè)程序。多個(gè)任務(wù)的執(zhí)行必須得輪流執(zhí)行,在系統(tǒng)里面進(jìn)行排隊(duì)等候。由于計(jì)算機(jī)的發(fā)展,要求系統(tǒng)功能越來越強(qiáng)大,這個(gè)時(shí)候出現(xiàn)了分時(shí)操作的概念:每個(gè)運(yùn)行的程序占有一定的處理機(jī)時(shí)間,當(dāng)這個(gè)占有時(shí)間結(jié)束后,在等待隊(duì)列等待處理器資源的下一個(gè)程序就開始投入運(yùn)行。注意這里的程序在占有一定的處理器時(shí)間后并沒有運(yùn)行完畢,可能需要再一次或多次分配處理器時(shí)間。那么從這里可以看出,這樣的執(zhí)行方式顯然是多個(gè)程序的并行執(zhí)行,但是在宏觀上,我們感覺到多個(gè)任務(wù)是同時(shí)執(zhí)行的,因此多任務(wù)的概念就誕生了。每個(gè)運(yùn)行的程序都有自己的內(nèi)存空間,自己的堆棧和環(huán)境變量設(shè)置。每一個(gè)程序?qū)?yīng)一個(gè)進(jìn)程,代表著執(zhí)行一個(gè)大的任務(wù)。一個(gè)進(jìn)程可以啟動(dòng)另外一個(gè)進(jìn)程,這個(gè)被啟動(dòng)的進(jìn)程稱為子進(jìn)程。父進(jìn)程和子進(jìn)程的執(zhí)行只有邏輯上的先后關(guān)系,并沒有其他的關(guān)系,也就是說他們的執(zhí)行是獨(dú)立的。但是,可能一個(gè)大的程序(代表著一個(gè)大的任務(wù)),可以分割成很多的小任務(wù),為了功能上的需要也有可能是為了加快運(yùn)行的速度,可能需要同一時(shí)間執(zhí)行多個(gè)任務(wù)(每個(gè)任務(wù)分配一個(gè)多線程來執(zhí)行相應(yīng)的任務(wù))。舉個(gè)例子來說,你正在通過你的web瀏覽器查看一些精彩的文章,你需要把好的文章給下載下來,可能有些非常精彩的文章你需要收藏起來,你就用你的打印機(jī)打印這些在線的文章。在這里,瀏覽器一邊下載HTML格式的文章,一邊還要打印文章。這就是一個(gè)程序同時(shí)執(zhí)行多個(gè)任務(wù),每個(gè)任務(wù)分配一個(gè)線程來完成。因此我們可以看出一個(gè)程序同時(shí)執(zhí)行多個(gè)任務(wù)的能力是通過多線程來實(shí)現(xiàn)的。


            多線程VS多任務(wù)

              正如上面所說的,多任務(wù)是相對與操作系統(tǒng)而言,指的是同一時(shí)間執(zhí)行多個(gè)程序的能力,雖然這么說,但是實(shí)際上在只有一個(gè)CPU的條件下不可能同時(shí)執(zhí)行兩個(gè)以上的程序。CPU在程序之間做高速的切換,使得所有的程序在很短的時(shí)間之內(nèi)可以得到更小的CPU時(shí)間,這樣從用戶的角度來看就好象是同時(shí)在執(zhí)行多個(gè)程序。多線程相對于操作系統(tǒng)而言,指的是可以同時(shí)執(zhí)行同一個(gè)程序的不同部分的能力,每個(gè)執(zhí)行的部分被成為線程。所以在編寫應(yīng)用程序時(shí),我們必須得很好的設(shè)計(jì)以 避免不同的線程執(zhí)行時(shí)的相互干擾。這樣有助于我們設(shè)計(jì)健壯的程序,使得我們可以在隨時(shí)需要的時(shí)候添加線程。


            線程的概念

              線程可以被描述為一個(gè)微進(jìn)程,它擁有起點(diǎn),執(zhí)行的順序系列和一個(gè)終點(diǎn)。它負(fù)責(zé)維護(hù)自己的堆棧,這些堆棧用于異常處理,優(yōu)先級(jí)調(diào)度和其他一些系統(tǒng)重新恢復(fù)線程執(zhí)行時(shí)需要的信息。從這個(gè)概念看來,好像線程與進(jìn)程沒有任何的區(qū)別,實(shí)際上線程與進(jìn)程是肯定有區(qū)別的:

              一個(gè)完整的進(jìn)程擁有自己獨(dú)立的內(nèi)存空間和數(shù)據(jù),但是同一個(gè)進(jìn)程內(nèi)的線程是共享內(nèi)存空間和數(shù)據(jù)的。一個(gè)進(jìn)程對應(yīng)著一段程序,它是由一些在同一個(gè)程序里面獨(dú)立的同時(shí)的運(yùn)行的線程組成的。線程有時(shí)也被稱為并行運(yùn)行在程序里的輕量級(jí)進(jìn)程,線程被稱為是輕量級(jí)進(jìn)程是因?yàn)樗倪\(yùn)行依賴與進(jìn)程提供的上下文環(huán)境,并且使用的是進(jìn)程的資源。

              在一個(gè)進(jìn)程里,線程的調(diào)度有搶占式或者非搶占的模式。

              在搶占模式下,操作系統(tǒng)負(fù)責(zé)分配CPU時(shí)間給各個(gè)進(jìn)程,一旦當(dāng)前的進(jìn)程使用完分配給自己的CPU時(shí)間,操作系統(tǒng)將決定下一個(gè)占用CPU時(shí)間的是哪一個(gè)線程。因此操作系統(tǒng)將定期的中斷當(dāng)前正在執(zhí)行的線程,將CPU分配給在等待隊(duì)列的下一個(gè)線程。所以任何一個(gè)線程都不能獨(dú)占CPU。每個(gè)線程占用CPU的時(shí)間取決于進(jìn)程和操作系統(tǒng)。進(jìn)程分配給每個(gè)線程的時(shí)間很短,以至于我們感覺所有的線程是同時(shí)執(zhí)行的。實(shí)際上,系統(tǒng)運(yùn)行每個(gè)進(jìn)程的時(shí)間有2毫秒,然后調(diào)度其他的線程。它同時(shí)他維持著所有的線程和循環(huán),分配很少量的CPU時(shí)間給線程。 線程的的切換和調(diào)度是如此之快,以至于感覺是所有的線程是同步執(zhí)行的。

              調(diào)度是什么意思?調(diào)度意味著處理器存儲(chǔ)著將要執(zhí)行完CPU時(shí)間的進(jìn)程的狀態(tài)和將來某個(gè)時(shí)間裝載這個(gè)進(jìn)程的狀態(tài)而恢復(fù)其運(yùn)行。然而這種方式也有不足之處,一個(gè)線程可以在任何給定的時(shí)間中斷另外一個(gè)線程的執(zhí)行。假設(shè)一個(gè)線程正在向一個(gè)文件做寫操作,而另外一個(gè)線程中斷其運(yùn)行,也向同一個(gè)文件做寫操作。 Windows 95/NT, UNIX使用的就是這種線程調(diào)度方式。

              在非搶占的調(diào)度模式下,每個(gè)線程可以需要CPU多少時(shí)間就占用CPU多少時(shí)間。在這種調(diào)度方式下,可能一個(gè)執(zhí)行時(shí)間很長的線程使得其他所有需要CPU的線程”餓死”。在處理機(jī)空閑,即該進(jìn)程沒有使用CPU時(shí),系統(tǒng)可以允許其他的進(jìn)程暫時(shí)使用CPU。占用CPU的線程擁有對CPU的控制權(quán),只有它自己主動(dòng)釋放CPU時(shí),其他的線程才可以使用CPU。一些I/O和Windows 3。x就是使用這種調(diào)度策略。

              在有些操作系統(tǒng)里面,這兩種調(diào)度策略都會(huì)用到。非搶占的調(diào)度策略在線程運(yùn)行優(yōu)先級(jí)一般時(shí)用到,而對于高優(yōu)先級(jí)的線程調(diào)度則多采用搶占式的調(diào)度策略。如果你不確定系統(tǒng)采用的是那種調(diào)度策略,假設(shè)搶占的調(diào)度策略不可用是比較安全的。在設(shè)計(jì)應(yīng)用程序的時(shí)候,我們認(rèn)為那些占用CPU時(shí)間比較多的線程在一定的間隔是會(huì)釋放CPU的控制權(quán)的,這時(shí)候系統(tǒng)會(huì)查看那些在等待隊(duì)列里面的與當(dāng)前運(yùn)行的線程同一優(yōu)先級(jí)或者更高的優(yōu)先級(jí)的線程,而讓這些線程得以使用CPU。如果系統(tǒng)找到一個(gè)這樣的線程,就立即暫停當(dāng)前執(zhí)行的線程和激活滿足條件的線程。如果沒有找到同一優(yōu)先級(jí)或更高級(jí)的線程,當(dāng)前線程還繼續(xù)占有CPU。當(dāng)正在執(zhí)行的線程想釋放CPU的控制權(quán)給一個(gè)低優(yōu)先級(jí)的線程,當(dāng)前線程就轉(zhuǎn)入睡眠狀態(tài)而讓低優(yōu)先級(jí)的線程占有CPU。

              在多處理器系統(tǒng),操作系統(tǒng)會(huì)將這些獨(dú)立的線程分配給不同的處理器執(zhí)行,這樣將會(huì)大大的加快程序的運(yùn)行。線程執(zhí)行的效率也會(huì)得到很大的提高,因?yàn)閷⒕€程的分時(shí)共享單處理器變成了分布式的多處理器執(zhí)行。這種多處理器在三維建模和圖形處理是非常有用的。


            需要多線程嗎

              我們發(fā)出了一個(gè)打印的命令,要求打印機(jī)進(jìn)行打印任務(wù),假設(shè)這時(shí)候計(jì)算機(jī)停止了響應(yīng)而打印機(jī)還在工作,那豈不是我們的停止手上的事情就等著這慢速的打印機(jī)打印?所幸的是,這種情況不會(huì)發(fā)生,我們在打印機(jī)工作的時(shí)候還可以同時(shí)聽音樂或者畫圖。因?yàn)槲覀兪褂昧霜?dú)立的多線程來執(zhí)行這些任務(wù)。你可能會(huì)對多個(gè)用戶同時(shí)訪問數(shù)據(jù)庫或者web服務(wù)器感到吃驚,他們是怎么工作的?這是因?yàn)闉槊總€(gè)連接到數(shù)據(jù)庫或者web服務(wù)器的用戶建立了獨(dú)立的線程來維護(hù)用戶的狀態(tài)。如果一個(gè)程序的運(yùn)行有一定的順序,這時(shí)候采用這種方式可能會(huì)出現(xiàn)問題,甚至導(dǎo)致整個(gè)程序崩潰。如果程序可以分成獨(dú)立的不同的任務(wù),使用多線程,即使某一部分任務(wù)失敗了,對其他的也沒有影響,不會(huì)導(dǎo)致整個(gè)程序崩潰。

              毫無疑問的是,編寫多線程程序使得你有了一個(gè)利器可以駕奴非多線程的程序,但是多線程也可能成為一個(gè)負(fù)擔(dān)或者需要不小的代價(jià)。如果使用的不當(dāng),會(huì)帶來更多的壞處。如果一個(gè)程序有很多的線程,那么其他程序的線程必然只能占用更少的CPU時(shí)間;而且大量的CPU時(shí)間是用于線程調(diào)度的;操作系統(tǒng)也需要足夠的內(nèi)存空間來維護(hù)每個(gè)線程的上下文信息;因此,大量的線程會(huì)降低系統(tǒng)的運(yùn)行效率。因此,如果使用多線程的話,程序的多線程必須設(shè)計(jì)的很好,否則帶來的好處將遠(yuǎn)小于壞處。因此使用多線程我們必須小心的處理這些線程的創(chuàng)建,調(diào)度和釋放工作。


            多線程程序設(shè)計(jì)提示

              有多種方法可以設(shè)計(jì)多線程的應(yīng)用程序。正如后面的文章所示,我將給出詳細(xì)的編程示例,通過這些例子,你將可以更好的理解多線程。線程可以有不同的優(yōu)先級(jí),舉例子來說,在我們的應(yīng)用程序里面,繪制圖形或者做大量運(yùn)算的同時(shí)要接受用戶的輸入,顯然用戶的輸入需要得到第一時(shí)間的響應(yīng),而圖形繪制或者運(yùn)算則需要大量的時(shí)間,暫停一下問題不大,因此用戶輸入線程將需要高的悠閑級(jí),而圖形繪制或者運(yùn)算低優(yōu)先級(jí)即可。這些線程之間相互獨(dú)立,相互不影響。

              在上面的例子中,圖形繪制或者大量的運(yùn)算顯然是需要站用很多的CPU時(shí)間的,在這段時(shí)間,用戶沒有必要等著他們執(zhí)行完畢再輸入信息,因此我們將程序設(shè)計(jì)成獨(dú)立的兩個(gè)線程,一個(gè)負(fù)責(zé)用戶的輸入,一個(gè)負(fù)責(zé)處理那些耗時(shí)很長的任務(wù)。這將使得程序更加靈活,能夠快速響應(yīng)。同時(shí)也可以使得用戶在運(yùn)行的任何時(shí)候取消任務(wù)的可能。在這個(gè)繪制圖形的例子中,程序應(yīng)該始終負(fù)責(zé)接收系統(tǒng)發(fā)來的消息。如果由于程序忙于一個(gè)任務(wù),有可能會(huì)導(dǎo)致屏幕變成空白,這顯然需要我們的程序來處理這樣的事件。所以我必須得有一個(gè)線程負(fù)責(zé)來處理這些消息,正如剛才所說的應(yīng)該觸發(fā)重畫屏幕的工作。

              我們應(yīng)該把握一個(gè)原則,對于那些對時(shí)間要求比較緊迫需要立即得到相應(yīng)的任務(wù),我們因該給予高的優(yōu)先級(jí),而其他的線程優(yōu)先級(jí)應(yīng)該低于她的優(yōu)先級(jí)。偵聽客戶端請求的線程應(yīng)該始終是高的優(yōu)先級(jí),對于一個(gè)與用戶交互的用戶界面的任務(wù)來說,它需要得到第一時(shí)間的響應(yīng),其優(yōu)先級(jí)因該高優(yōu)先級(jí)。

            posted on 2006-12-07 15:03 醒目西西 閱讀(147) 評論(0)  編輯 收藏 引用
            国内精品久久久久影院亚洲| 亚洲国产一成人久久精品| 久久精品一本到99热免费| 久久久久久久久无码精品亚洲日韩 | 无码伊人66久久大杳蕉网站谷歌| 久久99精品国产麻豆宅宅| 久久精品国产亚洲av麻豆色欲| 久久久九九有精品国产| 久久久久无码国产精品不卡| 狠狠色婷婷久久一区二区| 婷婷久久综合九色综合98| 一本久久精品一区二区| 久久99精品国产99久久| 中文字幕无码久久久| 久久久久免费精品国产| 亚洲中文久久精品无码| 久久99精品国产麻豆婷婷| 久久综合亚洲欧美成人| 欧美日韩中文字幕久久久不卡| 久久精品国产亚洲精品2020 | 2021国产精品久久精品| av无码久久久久久不卡网站| 午夜精品久久久内射近拍高清| 国产91久久精品一区二区| 亚洲综合伊人久久大杳蕉| 久久久久免费视频| 伊人色综合久久天天| 久久精品天天中文字幕人妻| 亚洲精品无码久久久| 久久精品国产亚洲精品| 精品久久人人爽天天玩人人妻| 中文字幕无码免费久久| 久久人与动人物a级毛片| 无码人妻久久一区二区三区蜜桃| 精品国产婷婷久久久| 国产福利电影一区二区三区久久老子无码午夜伦不| 欧美国产成人久久精品| 久久人人爽人人爽人人爽| 狠狠精品久久久无码中文字幕| 国产精品久久久久久久久软件| 久久久国产视频|