Jump to content
  • Advertisement
Sign in to follow this  
Daniel Miller

[.net] locking in c#

This topic is 4825 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

edit: I was doing everything all wrong, but I still do not understand how to protect a variable from being accesse in another thread. Could you explain how? [Edited by - Daniel Miller on June 3, 2005 12:41:01 PM]

Share this post


Link to post
Share on other sites
Advertisement
Threading is a fairly large subject, here are some resources.

The easiest way to make a variable thread safe (if that is what you are asking) is to declare it with the volatile keyword.

Share this post


Link to post
Share on other sites
Actually, I was looking for the Monitor class, which locks a variable for a specific thread. I was looking at it so wrong you couldn't even imagine (I was trying to use 'lock' on a variable).

Share this post


Link to post
Share on other sites
Does Monitor grant exclusive access to an actual object on the heap?

edit: weird things are happenning when I try and use Monitor.Enter.

For one, when I try to lock a public field of an instance of a class, it highlights "for (int x = 0;" on the next line and then that a says that a 'System.ArgumentNullException' was thrown.

But that is only when I try to attach a monitor to the field itself. Attaching it to the entire object has no effect.


edit: Whenever I make a change, it works for the first run, then never works again.

edit2: It's now alternating between working and not working. When it doesn't work, the output is strangely uniform for something that should be somewhat random. It should be all '*' without any '#' (ignore the '%%%%%'), but when it doesn't work:

%%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% *
%%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% #
%%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% *
%%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% *
%%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% #
%%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% *
%%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% *
%%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% #
%%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% *
%%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% *
%%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% #
%%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% *
%%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% *
%%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% #
%%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% *
%%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% *
%%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% #
%%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% * %%%%% * %%%%% # %%%%% *


[Edited by - Daniel Miller on June 3, 2005 1:18:33 PM]

Share this post


Link to post
Share on other sites
I would like to chime in to prevent confusion and errors.

I don't know what turnpast means exactly with "make a variable thread-safe", but to my sense, putting the "volatile" keyword doesn't solve all problems with multithreading. It should not be confused with Java's "synchronized".

"volatile" is a lightweight way to make some code thread-safe, but you have to carefully understand what it does and what this implies. It doesn't solve all multithreading scenarioes, and that's why there's the lock semantic.

For example, defining x as a volatile int will not make "x += 3" thread-safe (because it's not atomic). The result could be incorrect, if another thread reads/writes x after the reading but before the writing.

A few pointers:
C# specs, section 10.4.3 volatile fields. Explains what a volatile field is, and gives a small example of how it can be used to make some thread-safe code.

System.Threading.Interlocked class. Offers some atomic primitives (increment, exchange, ...) that are generally implemented in a lightweight fashion (i.e. using atomic CPU instructions).

C# lock keyword. Explains what the lock instruction is, what it does, and some examples. Note that the suggestion about what to lock on aren't that good, and I suggest you to read: Choosing what to lock on also.

System.Threading namespace. Contains other threading related primitives for synchronization. Look at classes Interlocked, Monitor, Mutex, ReaderWriterLock, ...

I know this is a lot of materials, but making efficient multithreading code is no simple issue.

Good luck,
jods

Share this post


Link to post
Share on other sites
Thank you, but I am trying to make a single object un accessable from other threads. I am having the problems I mentioned above when I do so (I'm using monitor).

Share this post


Link to post
Share on other sites
Daniel, what about posting your code here ?

Monitor.Enter and Exit are used to build critical sections. That means section of code that are going to be executed by only one thread at a time. In C#, instead of calling Monitor directly, you can use the lock keyword. That's basically the same, but may be more readable. lock calls Monitor.Enter, add a try...finally block, and calls Monitor.Exit in the finally clause.

Enter is a blocking call that will "acquire" the object you pass to it. Which object you pass is totally irrelevant. Enter will block if another thread has already "acquired" the same object, until it releases it. A thread releases an object that it has acquired by calling Exit.

There is no way to grant "exclusive access" to an object in C#. You have to protect the sections of code that access this object instead (here encapsulation / thread-safe classes are an obvious benefit).

Share this post


Link to post
Share on other sites
Fixed the formatting, I think.

Main.cs:

using System;
using System.Threading;

namespace LockThreadingTest
{
public class MainClass
{
public static void Main()
{
Speaker speaker = new Speaker();
SpeakerUser user = new SpeakerUser(speaker);

Thread thread = new Thread(new ThreadStart(user.Run));
thread.Start();

Monitor.Enter(speaker);
for (int x = 0; x != 1000; ++x)
{
speaker.quote = "*";
Console.Write("%");
Console.Write("%");
Console.Write("%");
Console.Write("%");
Console.Write("%");
speaker.Speak();
}
Monitor.Exit(speaker);

thread.Abort();
thread.Join();

Console.Read();
}
}
}







Speaker.cs

using System;

namespace LockThreadingTest
{
public class Speaker
{
public void Speak()
{
Console.Write(" " + quote + " ");
}

public void SpeakForever()
{
while(true)
{
Console.Write(" " + quote + " ");
}
}

public string quote;
}
}




SpeakerUser.cs



[source  lang="c#"]
using System;
namespace LockThreadingTest
{
public class SpeakerUser
{
public SpeakerUser(Speaker speaker)
{
this.speaker = speaker;
}

public void Run()
{
while (true)
{
speaker.quote = "#";
}
}

private Speaker speaker;
}
}






That is the code as I have it.

I am trying to prevent speaker.quote from being over written in the other thread.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!