Thread racing, why do threads work so? - c#

I have two different result from exchanging two lines of code ( done = true with Console.Write() one )
If I put done = true, firstly, the result will be:
True
Else If I put Console.WriteLine() firstly, the result will be:
False
False
Why? ( see carefully, that bool variable is static! )
using System;
using System.Threading;
class Program
{
static bool done;
static void Main(string[] args)
{
new Thread(test).Start();
test();
}
static void test()
{
if (!done)
{
done = true;
Console.WriteLine(done);
}
}
}

My bet is that the Console.WriteLine will be enough work to keep the thread busy while the second call to test() has a chance to execute.
So basically the call to WriteLine delays the setting of done long enough for the second call to test to be able to test done and find it is still set as false.
If you leave it as shown, with done = true; before the write to the console then this will be set almost instantly and thus the second call to test will find done set to true and will therefore not perform the Console.WriteLine.
Hope that all makes sense.
I just found this which contains code very much like your question. If you didn't get your question from this page already, then I would suggest having a read as it explains in much more detail the cause of this effect.
With the follow key extract:
On a single-processor computer, a thread scheduler performs
time-slicing — rapidly switching execution between each of the active
threads. Under Windows, a time-slice is typically in the
tens-of-milliseconds region — much larger than the CPU overhead in
actually switching context between one thread and another (which is
typically in the few-microseconds region).
So essentially the call to Console.WriteLine is taking long enough for the processor to decide that it is time for the main thread to have another go before your extra thread is permitted to continue (and ultimate set the done flag)

Your code isn't thread safe, and the results will be unpredictable.
You need to lock access when reading / writing to the static boolean, like so:
static bool done;
static readonly object _mylock = new object();
static void Main()
{
//Application.EnableVisualStyles();
//Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new Form1());
new Thread(test).Start();
test();
Console.ReadKey();
}
static void test()
{
lock (_mylock)
{
if (!done)
{
Console.WriteLine(done);
done = true;
}
}
}
Edit : readonly thanks #d4wn

Looks like the scheduler just cut the CPU time from one thread after it's call of Console.Writeline and then gave it to the other thread, all before done was set to true.
Are you certain that it always prints False\nFalse when you call Console.Writeline before assigning done = true;? To my understanding, this should be quite random.

Each time a shared variable is accessed by one of the sharing threads must be protected by one of the syncronization techniques explicitly. The environment (clr..) doesn't do it for us, cause in the whole possible complexity of multithreading it would be impossible. So this definetely responsible and not easy task must be done by the developer, writing multithreading code.
I guess there you can find a great deal of necessary information:
Thread Synchronization (C# Programming Guide)

Related

A value from one thread influencing the path of another thread

I have a program which uses two client threads and a server. There is a point in my program where I want a value in one thread to influence the path of another thread.
More specifically, I have this code in the server:
class Handler
{
public void clientInteraction(Socket connection, bool isFirstThread, Barrier barrier)
{
string pAnswer = string.Empty;
string endGameTrigger = string.Empty;
//setup streamReaders and streamWriters
while(true) //infinite game loop
{
//read in a question and send to both threads.
pAnswer = sr.ReadLine();
Console.WriteLine(pAnswer);
awardPoints();
writeToConsole("Press ENTER to ask another question or enter 0 to end the game", isFirstThread);
if(isFirstThread == true)
{
endGameTrigger = Console.ReadLine(); //this is only assigning to one thread...
}
barrier.SignalAndWait();
if(endGameTrigger == "0")//...meaning this is never satisfied in one thread
{
endGame();
}
}
}
}
The boolean value isFirstThread is a value set up in the constructor of the thread to which I can detect which thread was connected first.
Is there some way, or perhaps a threading method, that will allow the second connected thread to detect that the endGameTrigger in the first thread has been set and therefore both threads execute the endGame() method properly.
It's best to be concerned with multithreading
If it's absolutely necessary to start a separate thread for performance/UI reasons
If your code may be running in a multithreaded environment (like a web site) and you need to know that it won't break when multiple threads operate on the same class or same values.
But exercise extreme caution. Incorrect use/handling of multiple threads can cause your code to behave unpredictably and inconsistently. Something will work most of the time and then not work for no apparent reason. Bugs will be difficult to reproduce and identify.
That being said, one of the essential concepts of handling multithreading is to ensure that two threads don't try to update the same value at the same time. They can corrupt or partially modify values in ways that would be impossible for a single thread.
One way to accomplish this is with locking.
private object _lockObject = new Object();
private string _myString;
void SetStringValue(string newValue)
{
lock(_lockObject)
{
_myString = newValue;
}
}
You generally have an object that exists only to serve as a lock. When one thread enters that lock block it acquires a lock on the object. If another thread already has a lock on that object then the next thread just waits for the previous thread to release the lock. That ensures that two threads can't update the value at the same time.
You want to keep the amount of code inside the lock as small as possible so that the lock is released as soon as possible. And be aware that if it gets complicated with multiple locks then two threads can permanently block each other.
For incrementing and updating numbers there are also interlocked operations that handle the locking for you, ensuring that those operations are executed by one thread at a time.
Just for fun I wrote this console app. It takes a sentence, breaks it into words, and then adds each word back onto a new string using multiple threads and outputs the string.
using System;
using System.Threading.Tasks;
namespace FunWithThreading
{
class Program
{
static void Main(string[] args)
{
var sentence =
"I am going to add each of these words to a string "
+ "using multiple threads just to see what happens.";
var words = sentence.Split(' ');
var output = "";
Parallel.ForEach(words, word => output = output + " " + word);
Console.WriteLine(output);
Console.ReadLine();
}
}
}
The first two times I ran it, the output string was exactly what I started with. Great, it works perfectly! Then I got this:
I am going to add of these words to a string using multiple threads just to see what happens. each
Then I ran it 20 more times and couldn't repeat the error. Just imagine the frustration if this was a real application and something unpredictable like this happened even though I tested over and over and over, and then I couldn't get it to happen again.
So the point isn't that multithreading is evil, but just to understand the risks, only introduce it if you need to, and then carefully consider how to prevent threads from interfering with each other.
In response to Luaan's comment. I have put the endGameTrigger as private static string endGameTrigger in the Handler class. Making it a static field instead of a local method variable allows all instances of the handler class (each thread) access to this variable's most recent assignation. Many thanks.

Do we really need VOLATILE keyword in C#?

Here is the code that I was trying on my workstation.
class Program
{
public static volatile bool status = true;
public static void Main()
{
Thread FirstStart = new Thread(threadrun);
FirstStart.Start();
Thread.Sleep(200);
Thread thirdstart = new Thread(threadrun2);
thirdstart.Start();
Console.ReadLine();
}
static void threadrun()
{
while (status)
{
Console.WriteLine("Waiting..");
}
}
static void threadrun2()
{
status = false;
Console.WriteLine("the bool value is now made FALSE");
}
}
As you can see I have fired three threads in Main. Then using breakpoints I tracked the threads. My initial conception was all the three threads will be fired simultaneously, but my breakpoint flow showed that the thread-execution-flow followed one after other (and so was the output format i.e. Top to bottom execution of threads). Guys why is that happening ?
Additionally I tried to run the same program without using the volatile keyword in declaration, and I found no change in program execution. I doubt the volatile keyword is of no practical live use. Am I going wrong somewhere?
Your method of thinking is flawed.
The very nature of threading related issues is that they're non-deterministic. This means that what you have observed is potentially no indicator of what may happen in the future.
This is the very nature of why multithreaded programming is "hard." It often defies ad hoc testing, or even most unit testing. The only way to do it effectively is to understand your entire software and hardware stack, and diagram every possible occurrence through use of state machines.
In summary, threaded programming is not about what you've seen happen, it's about what might possibly happen, no matter how improbable.
Ok I will try to explain a very long story as short as possible:
Number 1: Trying to inspect the behavior of threads with the debugger is as useful as repeatedly running a multithreaded program and concluding that it works fine because out of 100 tests none failed: WRONG! Threads behave in a completely nondeterministic (some would say random) way and you need different methods to make sure such a program will run correctly.
Number 2: The use of volatile will become clear once you remove it and then run your program in Debug mode and then switch to Release mode. I think you will have a surprise... What happens in Release mode is that the compiler will optimize code (this includes reordering instructions and caching of values). Now, if your two threads run on different processor cores, then the core executing the thread that is checking for the value of status will cache its value instead of repeatedly checking for it. The other thread will set it but the first one will never see the change: deadlock! volatile prevents this kind of situation from occurring.
In a sense, volatile is a guard in case the code does not actually (and most likely will not) run as you think it will in a multithreaded scenario.
The fact that your simple code doesn't behave dirrefently with volatile doesn't mean anything. Your code is too simple and has nothing to do with volatile. You need to write very computation-intensive code to create a clearly visible memory race condition.
Also, volatile keyword may be useful on other platforms than x86/x64 with other memory models. (I mean like for example Itanium.)
Joe Duffy wrote interesting information about volatile on his blog. I strongly recommend to read it.
Then using breakpoints I tracked the threads. My initial conception
was all the three threads will be fired simultaneously, but my
breakpoint flow showed that the thread-execution-flow followed one
after other (and so was the output format i.e. Top to bottom execution
of threads). Guys why is that happening?
The debugger is temporarily suspending the threads to make it easier to debug.
I doubt the volatile keyword is of no practical live use. Am I going
wrong somewhere?
The Console.WriteLine calls are very likely fixing masking the problem. They are most likely generating the necessary memory barrier for you implicitly. Here is a really simple snippet of code that demonstrates that there is, in fact, a problem when volatile is not used to declare the stop variable.
Compile the following code with the Release configuration and run it outside of the debugger.
class Program
{
static bool stop = false;
public static void Main(string[] args)
{
var t = new Thread(() =>
{
Console.WriteLine("thread begin");
bool toggle = false;
while (!stop)
{
toggle = !toggle;
}
Console.WriteLine("thread end");
});
t.Start();
Thread.Sleep(1000);
stop = true;
Console.WriteLine("stop = true");
Console.WriteLine("waiting...");
t.Join();
}
}

C# manual lock/unlock

I have a function in C# that can be called multiple times from multiple threads and I want it to be done only once so I thought about this:
class MyClass
{
bool done = false;
public void DoSomething()
{
lock(this)
if(!done)
{
done = true;
_DoSomething();
}
}
}
The problem is _DoSomething takes a long time and I don't want many threads to wait on it when they can just see that done is true.
Something like this can be a workaround:
class MyClass
{
bool done = false;
public void DoSomething()
{
bool doIt = false;
lock(this)
if(!done)
doIt = done = true;
if(doIt)
_DoSomething();
}
}
But just doing the locking and unlocking manually will be much better.
How can I manually lock and unlock just like the lock(object) does? I need it to use same interface as lock so that this manual way and lock will block each other (for more complex cases).
The lock keyword is just syntactic sugar for Monitor.Enter and Monitor.Exit:
Monitor.Enter(o);
try
{
//put your code here
}
finally
{
Monitor.Exit(o);
}
is the same as
lock(o)
{
//put your code here
}
Thomas suggests double-checked locking in his answer. This is problematic. First off, you should not use low-lock techniques unless you have demonstrated that you have a real performance problem that is solved by the low-lock technique. Low-lock techniques are insanely difficult to get right.
Second, it is problematic because we don't know what "_DoSomething" does or what consequences of its actions we are going to rely on.
Third, as I pointed out in a comment above, it seems crazy to return that the _DoSomething is "done" when another thread is in fact still in the process of doing it. I don't understand why you have that requirement, and I'm going to assume that it is a mistake. The problems with this pattern still exist even if we set "done" after "_DoSomething" does its thing.
Consider the following:
class MyClass
{
readonly object locker = new object();
bool done = false;
public void DoSomething()
{
if (!done)
{
lock(locker)
{
if(!done)
{
ReallyDoSomething();
done = true;
}
}
}
}
int x;
void ReallyDoSomething()
{
x = 123;
}
void DoIt()
{
DoSomething();
int y = x;
Debug.Assert(y == 123); // Can this fire?
}
Is this threadsafe in all possible implementations of C#? I don't think it is. Remember, non-volatile reads may be moved around in time by the processor cache. The C# language guarantees that volatile reads are consistently ordered with respect to critical execution points like locks, and it guarantees that non-volatile reads are consistent within a single thread of execution, but it does not guarantee that non-volatile reads are consistent in any way across threads of execution.
Let's look at an example.
Suppose there are two threads, Alpha and Bravo. Both call DoIt on a fresh instance of MyClass. What happens?
On thread Bravo, the processor cache happens to do a (non-volatile!) fetch of the memory location for x, which contains zero. "done" happens to be on a different page of memory which is not fetched into the cache quite yet.
On thread Alpha at the "same time" on a different processor DoIt calls DoSomething. Thread Alpha now runs everything in there. When thread Alpha is done its work, done is true and x is 123 on Alpha's processor. Thread Alpha's processor flushes those facts back out to main memory.
Thread bravo now runs DoSomething. It reads the page of main memory containing "done" into the processor cache and sees that it is true.
So now "done" is true, but "x" is still zero in the processor cache for thread Bravo. Thread Bravo is not required to invalidate the portion of the cache that contains "x" being zero because on thread Bravo neither the read of "done" nor the read of "x" were volatile reads.
The proposed version of double-checked locking is not actually double-checked locking at all. When you change the double-checked locking pattern you need to start over again from scratch and re-analyze everything.
The way to make this version of the pattern correct is to make at least the first read of "done" into a volatile read. Then the read of "x" will not be permitted to move "ahead" of the volatile read to "done".
You can check the value of done before and after the lock:
if (!done)
{
lock(this)
{
if(!done)
{
done = true;
_DoSomething();
}
}
}
This way you won't enter the lock if done is true. The second check inside the lock is to cope with race conditions if two threads enter the first if at the same time.
BTW, you shouldn't lock on this, because it can cause deadlocks. Lock on a private field instead (like private readonly object _syncLock = new object())
The lock keyword is just syntactic sugar for the Monitor class. Also you could call Monitor.Enter(), Monitor.Exit().
But the Monitor class itself has also the functions TryEnter() and Wait() which could help in your situation.
I know this answer comes several years late, but none of the current answers seem to address your actual scenario, which only became apparent after your comment:
The other threads don't need to use any information generated by ReallyDoSomething.
If the other threads don't need to wait for the operation to complete, the second code snippet in your question would work fine. You can optimize it further by eliminating your lock entirely and using an atomic operation instead:
private int done = 0;
public void DoSomething()
{
if (Interlocked.Exchange(ref done, 1) == 0) // only evaluates to true ONCE
_DoSomething();
}
Furthermore, if your _DoSomething() is a fire-and-forget operation, then you might not even need the first thread to wait for it, allowing it to run asynchronously in a task on the thread pool:
int done = 0;
public void DoSomething()
{
if (Interlocked.Exchange(ref done, 1) == 0)
Task.Factory.StartNew(_DoSomething);
}

recursively calling method (for object reuse purpose)

I have a rather large class which contains plenty of fields (10+), a huge array (100kb) and some unmanaged resources. Let me explain by example
class ResourceIntensiveClass
{
private object unmaganedResource; //let it be the expensive resource
private byte[] buffer = new byte[1024 * 100]; //let it be the huge managed memory
private Action<ResourceIntensiveClass> OnComplete;
private void DoWork(object state)
{
//do long running task
OnComplete(this); //notify callee that task completed so it can reuse same object for another task
}
public void Start(object dataRequiredForCurrentTask)
{
ThreadPool.QueueUserWorkItem(DoWork); //initiate long running work
}
}
The problem is that the start method never returns after the 10000th iteration causing a stack overflow. I could execute the OnComplete delegate in another thread giving a chance for the Start method to return, but it requires using extra cpu time and resources as you know. So what is the best option for me?
Is there a good reason for doing your calculations recursively? This seems like a simple loop would do the trick, thus obviating the need for incredibly deep stacks. This design seems especially problematic as you are relying on main() to setup your recursion.
recursive methods can get out of hand quite fast. Have you looked into using Parallel Linq?
you could do something like
(your Array).AsParallel().ForAll(item => item.CallMethod());
you could also look into the Task Parallel Library (TPL)
with tasks, you can define an action and a continue with task.
The Reactive Framework (RX) on the other hand could handle these on complete events in an async manner.
Where are you changing the value of taskData so that its length can ever equal currentTaskIndex? Since the tasks you are assigning to the data are never changing, they are being carried out forever...
I would guess that the problem arises from using the pre-increment operator here:
if(c.CurrentCount < 10000)
c.Start(++c.CurrentCount);
I am not sure of the semantics of pre-increment in C#, perhaps the value passed to a method call is not what you expect.
But since your Start(int) method assigns the value of the input to this.CurrentCount as it's first step anyway, you should be safe replacing this with:
if(c.CurrentCount < 10000)
c.Start(c.CurrentCount + 1);
There is no point in assigning to c.CurrentCount twice.
If using the threadpool, I assume you are protecting the counters (c.CurrentCount), otherwise concurrent increments will cause more activity, not just 10000 executions.
There's a neat tool called a ManualResetEvent that could simplify life for you.
Place a ManualResetEvent in your class and add a public OnComplete event.
When you declare your class, you can wire up the OnComplete event to some spot in your code or not wire it up and ignore it.
This would help your custom class to have more correct form.
When your long process is complete (I'm guessing this is in a thread), simply call the Set method of the ManualResetEvent.
As for running your long method, it should be in a thread that uses the ManualResetEvent in a way similar to below:
private void DoWork(object state)
{
ManualResetEvent mre = new ManualResetEvent(false);
Thread thread1 = new Thread(
() => {
//do long running task
mre.Set();
);
thread1.IsBackground = true;
thread1.Name = "Screen Capture";
thread1.Start();
mre.WaitOne();
OnComplete(this); //notify callee that task completed so it can reuse same object for another task
}

Easiest way to make a single statement async in C#?

I've got a single statement running on a ASP.NET page that takes a long time (by long I mean 100ms, which is too long if I want this page to be lightning fast) , and I don't care when it executes as long as executes.
What is the best (and hopefully easiest) way to accomplish this?
The easiest way is probably to get it to execute in the threadpool. For example, to make this asynchronous:
using System;
using System.Threading;
class Test
{
static void ExecuteLongRunningTask()
{
Console.WriteLine("Sleeping...");
Thread.Sleep(1000);
Console.WriteLine("... done");
}
static void Main()
{
ExecuteLongRunningTask();
Console.WriteLine("Finished");
Console.ReadLine();
}
}
Change the first line of Main to:
ThreadPool.QueueUserWorkItem(x => ExecuteLongRunningTask());
Be aware that if you pass any arguments in, they'll be captured variables - that could have subtle side-effects in some cases (particularly if you use it in a loop).
If it's 100ms, then don't bother. Your users can't detect a 100ms delay.
Edit: some explanations.
If I remember correctly, 100 milliseconds (1/10 second) is near the minimum amount of time that a human can perceive. So, for the purpose of discussion, let me grant that this 100ms can be perceived by the users of the OP's site, and that it is worthwhile to improve performance by 100ms. I assumed from the start that the OP had correctly identified this "long-running" task as a potential source of a 100ms improvement. So, why did I suggest he ignore it?
Dealing with multiple threads properly is not easy, and is a source of bugs that are difficult to track down. Adding threads to a problem is usually not a solution, but is rather a source of other problems you simply don't find right away (*).
I had the opportunity once to learn this the hard way, with a bug that could only be reproduced on the fastest eight-cpu system available at the time, and then only by pounding on the thing relentlessly, while simulating a degree of network failure that would have caused the network administrators to be lined up and shot, if it had happened in real life. The bug turned out to be in the Unix OS kernel handling of signals, and was a matter of the arrangement of a handful of instructions.
Granted I've never seen anything that bad since then, I've still seen many developers tripped up by multithreading bugs. This question, seemed to be, on the one hand, asking for an "easy way out" via threading, and on the other hand, the benefit was only 100ms. Since it did not appear that the OP already had a well-tested threading infrastructure, it seemed to me that it made better sense to ignore the 100ms, or perhaps to pick up performance some other way.
(*) Of course, there are many circumstances where an algorithm can profitably be made parallel and executed by multiple threads, running on multiple cores. But it does not sound like the OP has such a case.
There's a background worker thread that can be very useful when processing information in the background of a .NET application. A bit more context would help answer the question better.
// This is the delegate to use to execute the process asynchronously
public delegate void ExecuteBackgroundDelegate();
//
[STAThread]
static void Main(string[] args)
{
MyProcess proc = new MyProcess();
// create an instance of our execution delegate
ExecuteBackgroundDelegate asynchExec = new ExecuteBackgroundDelegate(proc.Execute);
// execute this asynchronously
asynchExec.BeginInvoke(null, null);
}
If you mean to say that the response can be sent before the command is ran, you could use ThreadPool.QueueUserWorkItem to run it on another thread without blocking your request.
you can use a ThreadPool.
ThreadPool.QueueUserWorkItem( o => Thread.Sleep(1000) /*your long task*/ );
class Test
{
void LongRunningTask()
{
Console.WriteLine("Sleeping...");
Thread.Sleep(10000);
Console.WriteLine("... done");
}
static void Main()
{
Test t = new Test();
new Action(() => t.LongRunningTask()).BeginInvoke(null, t);
}
}
I wouldn't bother with any of that threading stuff for a 100ms delay. This will do fine:
protected void Page_Unload(object sender, EventArgs e)
{
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.Close();
// Your code here
}
(copied from my earlier answer for this question)
Since the connection to the client downloading your page will be closed, their browser will stop displaying a loading message. Your code will continue execution normally however.

Categories

Resources