Sign in to follow this  

[.net] is it possible to dedicate a mutex to a specific name ?

This topic is 2491 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Create a global mutex, a global condition and a global list of all files currently being accessed.

Before accessing a file, lock the mutex and check the list if it is already being accessed. If it is being accessed, wait on the condition with the mutex until it is no longer being accessed. After that, add the file to the list of currently accessed files and unlock the mutex. Now just go ahead and do your thing with the file. When done, lock the global mutex again, remove the file from the list, signal the condition (signal all) and unlock again.

Share this post


Link to post
Share on other sites
[quote name='Ohforf sake' timestamp='1298237116' post='4776800']
Create a global mutex, a global condition and a global list of all files currently being accessed.

Before accessing a file, lock the mutex and check the list if it is already being accessed. If it is being accessed, wait on the condition with the mutex until it is no longer being accessed. After that, add the file to the list of currently accessed files and unlock the mutex. Now just go ahead and do your thing with the file. When done, lock the global mutex again, remove the file from the list, signal the condition (signal all) and unlock again.
[/quote]

thanks ,thats a good idea , i just didn't really understand the last part why would i lock the mutex when im done with the file ,
if the file isnt being handled now the mutex should be open ..

Share this post


Link to post
Share on other sites
You should lock it again for two reasons:
1. You are accessing a shared resource (the list of files)
2. You are signalling a condition which should almost always be done from within the mutex used in the condition. Otherwise thread A entering the method might check on the list, see that the file is in use, but be interrupted before waiting on the condition. Now thread B is resumed, leaving the method (thus removing the file from the list) and signaling the condition (it can do so because there is no mutex). Now since A was stopped before entering the condition, the signal can't reach thread A and when A resumes it will run straight into the condition and wait there for ever.

Maybe you should read up on the mutex and condition concepts, because multithreading is a bad place for trial and error.

Share this post


Link to post
Share on other sites
Or you could use a database and drop the xml file, i hear databases are well renowed for being accessed by multiple calls (read & or write) at a time ><

If you don't want to install a db server then use an in memory DB but i would definately not mess with shared ressources just for a logging activity.

Share this post


Link to post
Share on other sites

This topic is 2491 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this