I/O线程
CLR線程池分為工作者線程(workerThreads)與I/O線程(completionPortThreads)兩種:
- 工作者線程是主要用作管理CLR內(nèi)部對象的運(yùn)作,通常用于計算密集的任務(wù)。
- I/O(Input/Output)線程主要用于與外部系統(tǒng)交互信息,如輸入輸出,CPU僅需在任務(wù)開始的時候,將任務(wù)的參數(shù)傳遞給設(shè)備,然后啟動硬件設(shè)備即可。等任務(wù)完成的時候,CPU收到一個通知,一般來說是一個硬件的中斷信號,此時CPU繼續(xù)后繼的處理工作。在處理過程中,CPU是不必完全參與處理過程的,如果正在運(yùn)行的線程不交出CPU的控制權(quán),那么線程也只能處于等待狀態(tài),即使操作系統(tǒng)將當(dāng)前的CPU調(diào)度給其他線程,此時線程所占用的空間還是被占用,而并沒有CPU處理這個線程,可能出現(xiàn)線程資源浪費(fèi)的問題。如果這是一個網(wǎng)絡(luò)服務(wù)程序,每一個網(wǎng)絡(luò)連接都使用一個線程管理,可能出現(xiàn)大量線程都在等待網(wǎng)絡(luò)通信,隨著網(wǎng)絡(luò)連接的不斷增加,處于等待狀態(tài)的線程將會很消耗盡所有的內(nèi)存資源。可以考慮使用線程池解決這個問題。
?對于I/O線程,我們可以將輸入輸出操作分成三個步驟:啟動、實際輸入輸出、處理結(jié)果。用 于實際輸入輸出可由硬件完成,并不需要CPU的參與,而啟動和處理結(jié)果也可以不在同一個 線程上,這樣就可以充分利用線程資源。在.Net中通過以Begin開頭的方法來完成啟動,以 End開頭的方法來處理結(jié)果,這兩個方法可以運(yùn)行在不同的線程,這樣我們就實現(xiàn)了異步編 程了。
.NET為多個I/O操作都建立起了異步方法。例如:FileStream、TCP/IP、WebRequest、WebService等等。
APM模式:異步編寫模型是一種模式,該模式允許用更少的線程去做更多的操作,.NET Framework很多類也實現(xiàn)了該模式,同時我們也可以自定義類來實現(xiàn)該模式,(也就是在自定義的類中實現(xiàn)返回類型為IAsyncResult接口的BeginXXX方法和EndXXX方法)
EPM模式:是事件的異步編程模式的簡稱,?支持基于事件的異步模式的類將有一個或多個后綴為Async的方法,同時還會有一個相應(yīng)名為Completed后綴的事件,Async方法用于啟動異步處理,而Completed事件將在異步處理完成之后通過事件來宣告異步處理的完成。注意,在使用EPM模式的時候,不管是完成了異步請求,還是在處理中出現(xiàn)異常,或者是終止異步處理,都必須要調(diào)用Compeleted處理程序
?APM異步調(diào)用I/O線程
static void Main(string[] args) {//線程池中10個線程,10 I/O線程ThreadPool.SetMaxThreads(10, 10);//int maxThreads, portThreads;ThreadPool.GetAvailableThreads(out int maxThreads, out int portThreads);Console.WriteLine($"當(dāng)前最大線程數(shù):{maxThreads},最大I/O線程數(shù):{portThreads}");//文件名 文件創(chuàng)建方式 文件權(quán)限 文件進(jìn)程共享 緩沖區(qū)大小為1024 是否啟動異步I/O線程為trueFileStream stream = new FileStream(@"D:\123.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, 1024, true);//這里要注意,如果寫入的字符串很小,則.Net會使用輔助線程寫,因為這樣比較快byte[] bytes = Encoding.UTF8.GetBytes("hello");//異步寫入開始,倒數(shù)第二個參數(shù)指定回調(diào)函數(shù),最后一個參數(shù)將自身傳到回調(diào)函數(shù)里,用于結(jié)束異步線程stream.BeginWrite(bytes, 0, (int)bytes.Length, new AsyncCallback(Callback), stream);Console.ReadKey(); }static void Callback(IAsyncResult result) {//顯示線程池現(xiàn)狀Thread.Sleep(2000);//通過result.AsyncState再強(qiáng)制轉(zhuǎn)換為FileStream就能夠獲取FileStream對象,用于結(jié)束異步寫入FileStream stream = (FileStream)result.AsyncState;stream.EndWrite(result);stream.Flush();stream.Close(); }?
總結(jié)
- 上一篇: 为tornado自定义session
- 下一篇: 数学之路(3)-机器学习(3)-机器学习