簡體   English   中英

如何同步套接字服務器中的線程以寫入文件

[英]How to synchronize threads in socket server for writing to file

我正在寫一個套接字服務器,它接收許多客戶端請求寫入文件。 我有一個arraylist來存儲socketlisteners。 在我運行客戶端以發送最多25個請求之后,套接字服務器存儲了25個套接字偵聽器,並啟動了25個線程來接收數據並寫入文件。 運行后,我從服務器收到錯誤消息,它試圖訪問被另一個進程鎖定的同一文件。 我也得到空引用錯誤。 因此,同步線程以使所有請求得到處理並將所有數據寫入文件的最佳方法是什么。

任何幫助表示贊賞。 謝謝。 -CR

string data = Encoding.ASCII.GetString(byteBuffer,0, size);

if (!File.Exists(filepath))
{
    using (StreamWriter sw = File.CreateText(filepath))
    {
        sw.WriteLine(data);  
    }
}
else
{
    using (StreamWriter sw = File.AppendText(filepath))
    {
        sw.WriteLine(data);
    }
}

這是一個經典的Producer Consumer問題 ,您可以通過實現Pipeline模式輕松解決。

基本上所有線程都將寫入同一線程安全隊列,而不是文件。 並且您還需要一個線程,該線程將從共享集合中讀取所有可用請求,並將其寫入文件。

使用.NET 4.X,可以很容易地使用BlockingCollection類(該類是線程安全的集合)來實現的。

// request queue represented by a single string
var requestsQueue = new BlockingCollection<string>(); 

請求處理邏輯(在多個線程中運行)基本上只是將請求添加到隊列中:

requestsQueue.Add(request);

將請求轉儲到文件的線程/任務應通過以下方式消耗可用請求:

using (StreamWriter sw = File.CreateText(filepath))     
{         
    foreach (var request in requestsQueue.GetConsumingEnumerable())
    {
       sw.WriteLinerequest);
    }
}

在這種情況下,最好將對文件的訪問序列化,並通過同步隊列將所有寫請求轉發到單獨的線程,這有兩個主要原因:

  1. 從多個線程向機械磁盤上​​的單個文件進行寫入/讀取不會產生任何性能上的好處(如果有很多線程,您甚至會發現性能下降)。
  2. 您將避免很多同步問題,特別是如果您使用預定義的同步隊列之一(例如ConcurrentQueue) ,則尤其如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM