多線程讀寫文件一直是一個比較常用的技術,普通的鎖顯得效率低下,和單線程感覺基本沒有啥區別,這里參考了大牛的代碼,采用了線程池技術,小菜我一直不明白異步和多線程有啥區別,后來讀了個大牛的博客,才明白,為加強理解,抄襲一下吧,
多線程相關名詞概念的解釋
並發:在操作系統中,是指一個時間段中有幾個程序都處於已啟動運行到運行完畢之間,且這幾個程序都是在同一個處理機上運行。
其中兩種並發關系分別是同步和互斥
- 互斥:進程間相互排斥的使用臨界資源的現象,就叫互斥。
- 同步:進程之間的關系不是相互排斥臨界資源的關系,而是相互依賴的關系。進一步的說明:就是前一個進程的輸出作為后一個進程的輸入,當第一個進程沒有輸出時第二個進程必須等待。具有同步關系的一組並發進程相互發送的信息稱為消息或事件。
其中並發又有偽並發和真並發,偽並發是指單核處理器的並發,真並發是指多核處理器的並發。
並行:在單處理器中多道程序設計系統中,進程被交替執行,表現出一種並發的外部特種;在多處理器系統中,進程不僅可以交替執行,而且可以重疊執行。在多處理器上的程序才可實現並行處理。從而可知,並行是針對多處理器而言的。並行是同時發生的多個並發事件,具有並發的含義,但並發不一定並行,也亦是說並發事件之間不一定要同一時刻發生。
異步和多線程並不是一個同等關系,異步是最終目的,多線程只是我們實現異步的一種手段。異步是當一個調用請求發送給被調用者,而調用者不用等待其結果的返回而可以做其它的事情。實現異步可以采用多線程技術或則交給另外的進程來處理。
如果都是獨占cpu 的業務, 比如舉杠鈴的業務, 在單核情況下 多線和單線 沒有區別。
總結
- 多線程的好處:比較容易的實現了異步切換的思想,
- 多線程本身程還是以同步完成,但是應該說比效率是比不上異步的。
- 多核的好處,就是可以同時做事情, 這個和單核完全不一樣的。
線程池異步讀寫文件
廢話不說了,直接上代碼,很好理解的
- 1
class Program
{
static void Main(string[] args)
{
//把線程池的最大值設置為1000
ThreadPool.SetMaxThreads(1000, 1000);
ThreadPoolMessage("Start");
#region 異步寫文件
//新立文件temp.txt
FileStream stream0 = new FileStream("temp.txt", FileMode.OpenOrCreate,FileAccess.ReadWrite, FileShare.ReadWrite, 1024, true);
byte[] bytes = new byte[16384];
string message = "An operating-system ThreadId...";
bytes = Encoding.Unicode.GetBytes(message);
//啟動異步寫入
stream0.BeginWrite(bytes, 0, (int)bytes.Length, new AsyncCallback(CallbackWrite), stream0);
stream0.Flush();
#endregion
//----------------------------------------------------
#region 異步讀文件
byte[] byteData = new byte[80961024];
FileStream stream1 = new FileStream("temp.txt", FileMode.OpenOrCreate,FileAccess.ReadWrite, FileShare.ReadWrite, 1024, true);
/*把FileStream對象,byte[]對象, 長度等有關數據綁定到FileData對象中, 以附帶屬性方式送到回調函數 */
FileData fileData = new FileData();
fileData.Stream = stream1;
fileData.Length = (int)stream1.Length;
fileData.ByteData = byteData;
//啟動異步讀取
stream1.BeginRead(byteData, 0, fileData.Length, new AsyncCallback(CallbackRead), fileData);
#endregion
Console.ReadKey();
}
/// <summary>
/// 寫文件的回調函數
/// </summary>
/// <param name="result"></param>
static void CallbackWrite(IAsyncResult result)
{
//顯示線程池現狀
Thread.Sleep(200);
ThreadPoolMessage("CallbackWrite");
//結束異步寫入
FileStream stream = (FileStream)result.AsyncState;
stream.EndWrite(result);
stream.Close();
}
//顯示線程池現狀
static void ThreadPoolMessage(string data)
{
int a, b;
ThreadPool.GetAvailableThreads(out a, out b);
string message = string.Format("{0}\n CurrentThreadId is {1}\n " +"WorkerThreads is:{2}
CompletionPortThreads is :{3}",
data, Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString());
Console.WriteLine(message);
}
public class FileData
{
public FileStream Stream;
public int Length;
public byte[] ByteData;
}
/// <summary>
/// 讀文件的回調函數
/// </summary>
/// <param name="result"></param>
static void CallbackRead(IAsyncResult result)
{
ThreadPoolMessage("CallbackRead");
//把AsyncResult.AsyncState轉換為FileData對象,以FileStream.EndRead完成異步讀取
FileData fileData = (FileData)result.AsyncState;
int length = fileData.Stream.EndRead(result);
fileData.Stream.Close();
//如果讀取到的長度與輸入長度不一致,則拋出異常
if (length != fileData.Length)
throw new Exception("Stream is not complete!");
string data = Encoding.ASCII.GetString(fileData.ByteData, 0, fileData.Length);
Console.WriteLine(data.Substring(2, 22));
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 1
</div><div><div></div></div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-60ecaf1f42.css" rel="stylesheet">
</div>