互斥体使用问题

发布于 2024-10-18 07:27:23 字数 2531 浏览 1 评论 0原文

在我的服务器上,我为每个客户端都有一个 xml 文件,其中包含客户端未收到的数据包。我需要访问服务器端的多个客户端文件。这是由多个后台线程发生的。

我正在寻找一种方法来创建特定文件的相互排斥。例如,假设 iv'e 有两个客户端 john 和 tom,并且在后台运行的方法 _AppendToUnsent

现在假设 john 有 2 个要追加的数据包,tom 有 3 个数据包。将为 john 和 tom 分派 2 个线程三个给汤姆。我不想阻止写入 tom.xml 的线程,因为另一个线程正在写入 john.xml

但我想阻止第二个线程尝试访问 john.xml,而另一个线程已经写入该文件

private static void _AppendToUnSent(object obj)
{
        append_packets_mutex.WaitOne();  // this will block all threads no matter if the writing to the same file or not
        // holds the name and the packet 
        KeyValuePair<String, byte[]> _pair = (KeyValuePair<String, byte[]>)obj;

        XmlDocument _doc = new XmlDocument();
        // build the path of the file 
        StringBuilder _builder = new StringBuilder();
        _builder.Append(_path);
        _builder.Append(_pair.Key);
        _builder.Append(".xml");
        if (!File.Exists(_builder.ToString()))
        {  // if the file dosent exist create it 
            XmlDeclaration xmlDeclaration = _doc.CreateXmlDeclaration("1.0", "utf-8", null);
            XmlElement rootNode = _doc.CreateElement(_pair.Value.ToString());
            _doc.InsertBefore(xmlDeclaration, _doc.DocumentElement);
            _doc.AppendChild(rootNode);
            XmlElement _packets_node = _doc.CreateElement("Packets");
            rootNode.AppendChild(_packets_node);

            _doc.Save(_builder.ToString());
        }

        try
        {
            _doc.Load(_builder.ToString());
        }
        catch (Exception es)
        {
            Console.WriteLine("Could Not save packet for " + _pair.Key);                
            return; 
        }
        // create and save a new <Packet> Node
        XmlNode declarition_node = _doc.FirstChild;// <Xml......>
        XmlNode packets_node = declarition_node.NextSibling;// <Messages>

        XmlElement _packet_node = _doc.CreateElement("Packet");// <Packet>

        _packet_node.InnerText = Convert.ToBase64String(_pair.Value);//43rg43g43yt42g.... // Encode to base64
        _packet_node.AppendChild(_packet_node);// <Packet>43rg43g43yt42g....</Packet>            
        try
        {
            _doc.Save(_builder.ToString());
        }
        catch (Exception es)
        {
            Console.WriteLine("Could Not save packet from " + _pair.Key);
        }
        append_packets_mutex.ReleaseMutex();  // realese the genrel mutex for this operaition 

} // end _AppendToUnsente here

on my server i've got an xml file for each client which holds the packets which the client had not received. i need to access multiple client files on a server side. This happens from multiple background threads.

i'm looking for a way to create mutual Exclusion an a specific file. For example let's say iv'e got two clients john and tom and the method running in the background _AppendToUnsent

now lets say john has 2 packets to append and tom has 3. 2 threads would be dispatched for john and three for tom. i don't want to block a thread writing to tom.xml because a different thread is writing to john.xml

i would however want to block a second thread trying to access john.xml while a different one is already writing to the file

private static void _AppendToUnSent(object obj)
{
        append_packets_mutex.WaitOne();  // this will block all threads no matter if the writing to the same file or not
        // holds the name and the packet 
        KeyValuePair<String, byte[]> _pair = (KeyValuePair<String, byte[]>)obj;

        XmlDocument _doc = new XmlDocument();
        // build the path of the file 
        StringBuilder _builder = new StringBuilder();
        _builder.Append(_path);
        _builder.Append(_pair.Key);
        _builder.Append(".xml");
        if (!File.Exists(_builder.ToString()))
        {  // if the file dosent exist create it 
            XmlDeclaration xmlDeclaration = _doc.CreateXmlDeclaration("1.0", "utf-8", null);
            XmlElement rootNode = _doc.CreateElement(_pair.Value.ToString());
            _doc.InsertBefore(xmlDeclaration, _doc.DocumentElement);
            _doc.AppendChild(rootNode);
            XmlElement _packets_node = _doc.CreateElement("Packets");
            rootNode.AppendChild(_packets_node);

            _doc.Save(_builder.ToString());
        }

        try
        {
            _doc.Load(_builder.ToString());
        }
        catch (Exception es)
        {
            Console.WriteLine("Could Not save packet for " + _pair.Key);                
            return; 
        }
        // create and save a new <Packet> Node
        XmlNode declarition_node = _doc.FirstChild;// <Xml......>
        XmlNode packets_node = declarition_node.NextSibling;// <Messages>

        XmlElement _packet_node = _doc.CreateElement("Packet");// <Packet>

        _packet_node.InnerText = Convert.ToBase64String(_pair.Value);//43rg43g43yt42g.... // Encode to base64
        _packet_node.AppendChild(_packet_node);// <Packet>43rg43g43yt42g....</Packet>            
        try
        {
            _doc.Save(_builder.ToString());
        }
        catch (Exception es)
        {
            Console.WriteLine("Could Not save packet from " + _pair.Key);
        }
        append_packets_mutex.ReleaseMutex();  // realese the genrel mutex for this operaition 

} // end _AppendToUnsente here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜司空 2024-10-25 07:27:23

您的选择:

  1. 由于您关心的是对磁盘上文件的单线程访问,因此您可以以独占读取模式打开该文件,这将阻止任何其他线程打开该文件,直到该文件关闭。
  2. 您可以使用命名互斥体,并使用文件名作为与该文件关联的互斥体的名称。

Your options:

  1. Since you are concerned with single thread access to a file on disk, you could open the file in exclusive read mode, which will prevent any other threads from opening the file until the file is closed.
  2. You could use named mutexes, and use the name of the file for the name of the mutex associated with the file.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文