是否可以将互斥锁专用于特定名称? [英] is it possible to dedicate a mutex to a specific name ?

查看:55
本文介绍了是否可以将互斥锁专用于特定名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,
在我的服务器iv上,每个客户端都有一个xml文件,其中包含客户端未接收到的数据包.
我需要访问服务器端的多个客户端文件,这是由多个后台线程引起的
我正在寻找一种创建特定文件互斥的方法
例如,假设iv''e有两个客户john和tom
以及在后台运行的方法(_AppendToUnsent)
现在让我们说john为2个要附加的数据包,而tom为3个
约翰将派出2个线程,而汤姆将派出3个线程
我不想阻止写入tom.xml的线程,因为另一个线程正在写入john.xml
我将如何在另一个已经写入文件的同时阻止另​​一个试图访问john.xml的线程

Hello,
on my server iv''e got an xml file for each client witch holds the packets witch 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 lets say iv''e got tow clients john and tom
and the method running in the background (_AppendToUnsent)
now lets say john as 2 packets to append ,and tom as 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 how ever 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

推荐答案

就像这样:
That would be something like this:
Mutex m = new Mutex(false, "TheFilenameWithoutPath.xml");



如此处记录:
http://msdn.microsoft.com/en-us/library/f55ddskf.aspx [ ^ ]

问候
Espen Harlinn



as documented here:
http://msdn.microsoft.com/en-us/library/f55ddskf.aspx[^]

Regards
Espen Harlinn


您的问题有些令人误解.它还需要更好的源代码格式才能被理解.当涉及互斥时,命名仅用于不同进程之间的同步.我认为这不是您所需要的;因此标题中的作品名称"具有误导性.

我想您的问题是互斥锁过度锁定.

首先,我可以看到代码中的基本问题.您的ReleaseMutex在出现异常时将被跳过;您需要在finally块下释放.另外,您在Exception es catch块下的异常处理只是一种犯罪(我想是对您自己的).你在干什么?!您正在阻止异常向上传播.在极少数情况下,您可以执行此操作(通常可以解决一些您的补丁程序无法访问的第三方代码).在大多数其他情况下,您应该仅在每个线程的堆栈顶部仅阻止异常处理(以避免不可恢复的情况).

通常,有时您确实确实需要像Mutex一样进行锁定,但不需要互锁处理不相关数据部分的不同线程.为此,请使用lock(LockObject) {}而不是Mutex.如果在不同的"lock"语句中使用不同的对象,则此类锁不会互锁,而是将具有相同锁对象的锁互锁.这等效于使用Mutex的多个不同实例,但是您完全不需要Mutex,因为lock就足够了.另外,使用lock时,您不需要try... finally块(lock块完全等于结合了try... finally块的关键部分).

这只是用于更改代码的技术信息.
至于您的代码设计,它看起来并不正确.我现在不能为您提供解决方案,因为您没有使用相同的Mutex或锁共享最终目标和代码的其他部分.

如果您想提出后续问题:

重要!请不要将其发布为问题(常见错误),请使用改进答案",在其他情况下,请使用添加评论".

—SA
You question is somewhat misleading. It also would need source better code formatting to be understood. When it comes to mutex, naming is used only for synchronization between different processes. I think this is not what you need; so the work "name" in your title is misleading.

I guess your problem is over-locking with mutex.

First, I can see essential problems in code. Your ReleaseMutex will be skipped on exception; you need to release under finally block. Also, your exception handling under Exception es catch block is simply a crime (against yourself, I guess). What are you doing?! You''re blocking exception propagation up the stack. There are very rare cases when you can do this (usually to work around some third-party code which is not accessible for your patch). In most other cases you should only block exception handling only of very top of your stack in each thread (to avoid non-recoverable situation).

Generally, sometimes you really need to do locking like with Mutex but not inter-lock different threads working on unrelated parts of data. For this purpose use lock(LockObject) {}, instead of Mutex. If you use different objects in different "lock" statements, such locks do not inter-lock each other, but the locks with identical lock objects to. This is equivalent to using several different instances of Mutex, but you don''t need Mutex at all, as lock is enough. Also, with lock you don''t need a try... finally blocks (lock block is perfectly equivalent of critical section combined with try... finally blocks).

This is just technical information for you to be used to change your code.
As to your code''s design, it does not look correct. I cannot suggest you a solution right now, because you did not share you ultimate goals and the other part of the code using same Mutex or lock.

In case you want to ask follow-up Question:

Important! Please don''t post it as a Question (a common mistake), use "Improve Answer", in other cases, use "Add comment".

—SA


这篇关于是否可以将互斥锁专用于特定名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆