Locking is not working - c#

This is my code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication4
{
class Writer {
public void Write(string xxx) { Console.Write(xxx); }
}
class Program
{
static Writer wrt;
static void Main(string[] args)
{
wrt = new Writer();
Thread trd = new Thread(new ThreadStart(delegate() {
lock (wrt)
{
Thread.Sleep(1000);
wrt.Write("1");
}
}));
trd.Start();
wrt.Write("0");
Console.ReadLine();
}
}
}
The excepted output is "10", but the output is "01". Why?

You need to lock in both places:
wrt = new Writer();
Thread trd = new Thread(new ThreadStart(delegate() {
lock (wrt)
{
Thread.Sleep(1000);
wrt.Write("1");
}
}));
trd.Start();
lock(wrt) // Lock here, too
{
wrt.Write("0");
}
Console.ReadLine();
Using a lock doesn't prevent that instance from being used other places, it just prevents that instance from being used to acquire another lock until your lock is done.
Instead of thinking of lock as "locking the object", think of it as your object is the one and only key for that lock - no other lock(yourObject) can "unlock" that block of code until the first one is done.
Note that this will still likely show "01" as output, as it's very unlikely that the thread will startup quickly enough to get the lock first, but that's not deterministic.

Why not use Tasks? It will ensure that the first thread is complete before continuing with the next thread.
class Program
{
static void Main(string[] args)
{
var writer = new Writer();
var task = Task.Factory.StartNew(() =>
{
writer.Write("1");
});
task.ContinueWith((data) =>
{
writer.Write("0");
});
Console.ReadKey();
}
}
public class Writer
{
public void Write(string message)
{
Console.Write(message);
}
}

The statement wrt.Write("0"); in the main thread is executed before the trd thread. The main thread starts the trd thread and keeps executing the statements those come under main thread thats why the Write statement under main thread is executing before trd thread.
The lock statement is inside trd thread and thus has nothing to do with wrt.Write under main thread. You can put lock on main thread as Reed Copsey suggested but you can not ensure which thread will get lock first. It could be main thread which gets the lock first.
You can ensure the trd thread finsishes execution prior to main thread by calling Thread.Join after starting thread trd, it will ensure main thread will wait until trd thread finishes the exectuion. This will ensure that you get 10 instead of 01.
static Writer wrt;
static void Main(string[] args)
{
wrt = new Writer();
Thread trd = new Thread(new ThreadStart(delegate() {
lock (wrt)
{
Thread.Sleep(1000);
wrt.Write("1");
}
}));
trd.Start();
trd.Join();
wrt.Write("0");
Console.ReadLine();
}

Related

Out of memory exception while playing with Monitor.Wait and Monitor.Pulse

I was playing with the Monitor class in .NET so I arrived at a piece of code that seem to be working but when I loop it for a while it throws an OutOfMemoryException.
I am running this on a 64 bit windows 8 developer machine with 8 GB of RAM and I the process never takes up more than a 100 MB of space on the RAM.
This is my code:
using System;
using System.Threading;
public class Program
{
public static void Main()
{
while (true) {
object theLock = new Object();
Thread threadA = new Thread(() =>
{
Console.WriteLine("Thread A before lock");
lock (theLock)
{
Console.WriteLine("Thread A locking, about to Wait");
Monitor.Wait(theLock);
}
Console.WriteLine("Thread A after lock");
});
Thread threadB = new Thread(() =>
{
Console.WriteLine("Thread B before lock");
lock (theLock)
{
Console.WriteLine("Thread B lockint, about to Pulse");
Monitor.Pulse(theLock);
}
Console.WriteLine("Thread B before lock");
});
threadA.Start();
threadB.Start();
GC.Collect();
}
}
}
I read here that it might be a fragmentation problem and I added the GC.Collect() at the end. However I am not allocating big chunks of space.
Then I decided to measure how many iterations does the loop go through approximately before it throws the exception and added a counter:
using System;
using System.Threading;
public class Program
{
public static void Main()
{
int counter = 0;
while (true) {
Console.WriteLine(counter);
counter++;
object theLock = new Object();
Thread threadA = new Thread(() =>
{
Console.WriteLine("Thread A before lock");
lock (theLock)
{
Console.WriteLine("Thread A locking, about to Wait");
Monitor.Wait(theLock);
}
Console.WriteLine("Thread A after lock");
});
Thread threadB = new Thread(() =>
{
Console.WriteLine("Thread B before lock");
lock (theLock)
{
Console.WriteLine("Thread B lockint, about to Pulse");
Monitor.Pulse(theLock);
}
Console.WriteLine("Thread B before lock");
});
threadA.Start();
threadB.Start();
GC.Collect();
}
}
}
That seems to slow down the throwing of the exception a lot. I measured 36000 iterations.
For each pair of threads, if thread A manages to acquire the lock before thread B, you'll end up with both threads completing, and everything can be cleaned up.
If thread B manages to acquire the lock before thread A, thread B will complete (having pulsed the monitor) but then thread A will acquire the monitor and wait forever for something to pulse it. So at that point you'll have:
A Thread object
An OS thread
The object that the thread is waiting on
... all of which are tied up forever, basically.
Given that, I'm not surprised that you're seeing problems.
It's not clear what you're trying to achieve, but that explains the symptoms. Never assume that just because you call threadA.Start() before threadB.Start(), the first thread will actually reach a certain point in code before the second thread.

Can't reproduce threading deadlock with MethodImplOptions.Synchronized

I'm trying to reproduce some deadlock with only MethodImplOptions.Synchronized method notation:
using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.CompilerServices;
namespace Lab_01
{
class Program1
{
[MethodImpl(MethodImplOptions.Synchronized)]
static void Resource1(int starterIndex, bool startNext = true)
{
Console.WriteLine("Resource1 is used ({0})", starterIndex);
Thread.Sleep(1000);
if (startNext)
{
Resource2(starterIndex, false);
}
Console.WriteLine("Resource1 is free ({0})", starterIndex);
}
[MethodImpl(MethodImplOptions.Synchronized)]
static void Resource2(int starterIndex, bool startNext = true)
{
Console.WriteLine("Resource2 is used ({0})", starterIndex);
Thread.Sleep(1000);
if (startNext)
{
Resource1(starterIndex, false);
}
Console.WriteLine("Resource2 is free ({0})", starterIndex);
}
static void Main(string[] args)
{
Locker locker1 = new Locker();
Locker locker2 = new Locker();
new Thread(delegate()
{
Resource1(0);
}).Start();
new Thread(delegate()
{
Resource2(1);
}).Start();
}
}
}
What I expect is
1st thread is started and only the Resource1 method is locked, it waits for 1 sec
While 1st thread is sleeping (this 1 second) 2nd thread is started and it locks the 2nd resource (Resource2). It sleeps for 1 sec.
The thread, which ends the sleep first, say 1st thread, want to lock the 2nd resource, but it can't because it's already locked, and can't be freed, because the second thread is in the same situation (it wants to lock Recource1, but it's already locked). In one word, the regular deadlock situation.
But when I start it it doesn't lock itself and I'm getting this output:
C:\Users\ginz\C#\19-\Lab_01\Lab_01\bin\Debug>Lab_01.exe
Resource1 is used (0)
Resource2 is used (0)
Resource2 is free (0)
Resource1 is free (0)
Resource2 is used (1)
Resource1 is used (1)
Resource1 is free (1)
Resource2 is free (1)
So, the second thread is started only when the first thread has come to the end, but I think it should start much earlier. Why is this?
I know this behavior can be simply reproduced by using lock keyword, but in my case that's inappropriate way:
Object obj1 = new Object(), obj2 = new Object();
new Thread(new ThreadStart(delegate()
{
lock (obj1)
{
Thread.Sleep(1000);
lock (obj2)
{
Thread.Sleep(500);
}
}
})).Start();
new Thread(new ThreadStart(delegate()
{
lock (obj2)
{
Thread.Sleep(1000);
lock (obj1)
{
Thread.Sleep(500);
}
}
})).Start();
Could you please help me in this situation?
Thanks in advance,
Dmitry

Monitor.Pulse(this) does not trigger Monitor.Wait(this);

I'm trying to get Monitor.Pulse(this) to trigger Monitor.Wait(this) in my code. I think my Wait statements are all running at some point with no Pulse. I have 5 different threads run by 5 different objects, each representing a queue with different priority. I'm trying to get each thread to run with a certain priority without using the thread priority attribute (i.e. normal, abovenormal, etc.). Anyways, point is that each thread only runs once and then it seems they are stuck at the Monitor.Wait(this) part in the thread that runs for each queue. Does anyone know why the Monitor.Pulse(this) doesn't trigger the Monitor.Wait(this) and continue the cycle. Each thread should be triggered one after the other by the Monitor.Wait(this) and the while loop that uses the Global variable GlobalCount. I think the problem must occur in my Beta method in the first class (Msg class) at the top where this triggering occurs. Or in my main method, although I'm less sure of that part having an issue.
What happens is it will execute a few lines and then start a new line but won't print anything else. The code is still running. I also tried removing the Monitor.Pulse and Monitor.Wait and it partially works, but every time the delta object's beta method runs its thread it is replaced by the alpha method. Does anyone know why this is and how I can get Pulse and Wait to work?
Here is my code (ignore some of the comments):
// StopJoin.cs
using System;
using System.Threading;
using System.Collections;
public class Msg
{
string message;
int priority;
public Msg(string ms, int pr)
{message = ms;
priority = pr;}
// This method that will be called when the thread is started
public void Beta()
{
while(true){
//Console.WriteLine("asdfasdfs");
Console.WriteLine(message+":"+GlobalClass.globalCount);
lock(this) // Enter synchronization block
{
while((priority - 1) != GlobalClass.globalCount){
//Console.WriteLine(GlobalClass.globalCount);
try
{
// Waits for the Monitor.Pulse in WriteToCell
//Console.WriteLine("beginning");
//Monitor.Wait(this);
//Console.WriteLine("end");
}
catch (SynchronizationLockException e)
{
Console.WriteLine(e);
}
catch (ThreadInterruptedException e)
{
Console.WriteLine(e);
}
if(GlobalClass.globalCount >= 5)
GlobalClass.globalCount = 0;
}
Console.WriteLine(message+".Beta is running in its own thread.");
for(int i = 0;i<priority;i++)
{
Console.WriteLine("sending message...");
}
if(GlobalClass.globalCount < 5)
GlobalClass.globalCount = GlobalClass.globalCount + 1;
//Monitor.Pulse(this); // Pulse tells Cell.WriteToCell that
//Console.WriteLine(GlobalClass.globalCount);
}
}
}
}
public class Alpha
{
Msg the_message = new Msg("Alpha",1);
public void doWork()
{the_message.Beta();}
};
public class Charlie
{
Msg the_message = new Msg("Charlie",2);
public void doWork()
{the_message.Beta();}
};
public class Delta
{
Msg the_message= new Msg("Alpha",3);
public void doWork()
{the_message.Beta();}
};
public class Echo
{
Msg the_message= new Msg("Echo",4);
public void doWork()
{the_message.Beta();}
};
public class Foxtrot
{
Msg the_message= new Msg("Foxtrot",5);
public void doWork()
{the_message.Beta();}
};
static class GlobalClass
{
private static int global_count = 0;
public static int globalCount
{
get{return global_count;}
set{global_count = value;}
}
}
public class Simple
{
public static int Main()
{
GlobalClass.globalCount = 2;
long s = 0;
long number = 100000000000000000;
Console.WriteLine("Thread Start/Stop/Join Sample");
Alpha oAlpha = new Alpha();
Charlie oCh = new Charlie();
Delta oDe = new Delta();
Echo oEc = new Echo();
Foxtrot oFo = new Foxtrot();
// Create the thread object, passing in the Alpha.Beta method
// via a ThreadStart delegate. This does not start the thread.
Thread oThread = new Thread(new ThreadStart(oAlpha.doWork));
Thread aThread = new Thread(new ThreadStart(oCh.doWork));
Thread bThread = new Thread(new ThreadStart(oDe.doWork));
Thread cThread = new Thread(new ThreadStart(oEc.doWork));
Thread dThread = new Thread(new ThreadStart(oFo.doWork));
// Start the thread
oThread.Start();
aThread.Start();
bThread.Start();
cThread.Start();
dThread.Start();
// Spin for a while waiting for the started thread to become
// alive:
while (!oThread.IsAlive);
while (!aThread.IsAlive);
while (!bThread.IsAlive);
while (!cThread.IsAlive);
while (!dThread.IsAlive);
// Put the Main thread to sleep for 1 millisecond to allow oThread
// to do some work:
Thread.Sleep(1);
// Wait until oThread finishes. Join also has overloads
// that take a millisecond interval or a TimeSpan object.
oThread.Join();
aThread.Join();
bThread.Join();
cThread.Join();
dThread.Join();
Console.WriteLine();
Console.WriteLine("Alpha.Beta has finished");
/*
try
{
Console.WriteLine("Try to restart the Alpha.Beta thread");
oThread.Start();
}
catch (ThreadStateException)
{
Console.Write("ThreadStateException trying to restart Alpha.Beta. ");
Console.WriteLine("Expected since aborted threads cannot be restarted.");
}
*/
while(s<number)
s++;
// Request that oThread be stopped
oThread.Abort();
aThread.Abort();
bThread.Abort();
cThread.Abort();
dThread.Abort();
return 0;
}
}
I can see a number of problems with your code, but there are two main ones that will be affecting you. I've assumed that your commented out Monitor calls shouldn't be commented (else the code makes no sense).
Firstly, you create a new instance of Msg under each thread. The Beta method locks on the current instance of Msg (in the commented Monitor.Wait(this)), and so each instance is essentially waiting on itself - which will be an infinite wait, because the only Monitor.Pulse is later in the same method, and will never be reached.
Because some of your Msg instances will be created with a higher value for priority, they will skip the while loop entirely and should continue to call Monitor.Pulse, but there will be nothing waiting on that pulse.
Later in your Main method, you have the following:
while (!oThread.IsAlive) ;
while (!aThread.IsAlive) ;
while (!bThread.IsAlive) ;
while (!cThread.IsAlive) ;
while (!dThread.IsAlive) ;
This is flawed. Because there's no guarantee of the execution order of your threads, it's entirely possible for the above code to deadlock. If your oThread isn't started immediately, but dThread is scheduled and runs to completion, you could easily see a case where dThread is completed and "dead" before the final line above is reached.
All in all, I'm not clear on what your code is trying to achieve, but as it stands I'd expect it to deadlock every time.

how threads communicate with eachother?

how threads communicate with eachother? they dont use values of eachother, then what is the way of communication between them?
There are a few ways threads can communicate with each other. This list is not exhaustive, but does include the most used strategies.
Shared memory, like a variable or some other data structure
Synchronization primitives, like locks and sempahores
Events, like ManualResetEvent or AutoResetEvent
Shared memory
public static void Main()
{
string text = "Hello World";
var thread = new Thread(
() =>
{
Console.WriteLine(text); // variable read by worker thread
});
thread.Start();
Console.WriteLine(text); // variable read by main thread
}
Synchronization primitives
public static void Main()
{
var lockObj = new Object();
int x = 0;
var thread = new Thread(
() =>
{
while (true)
{
lock (lockObj) // blocks until main thread releases the lock
{
x++;
}
}
});
thread.Start();
while (true)
{
lock (lockObj) // blocks until worker thread releases the lock
{
x++;
Console.WriteLine(x);
}
}
}
Events
public static void Main()
{
var are = new AutoResetEvent(false);
var thread = new Thread(
() =>
{
while (true)
{
Thread.Sleep(1000);
are.Set(); // worker thread signals the event
}
});
thread.Start();
while (are.WaitOne()) // main thread waits for the event to be signaled
{
Console.WriteLine(DateTime.Now);
}
}
"they don't use values of each other" - well two threads in the same process can see common variables, so that's the simples appraoch. So we use various synchronization, locking, mutices and sempahores to wait for conditions and wake up waiting threads.
In Java you use various primitives such as synchronization. You could read this tutorial
Threads can share values, they just have to be careful when doing so. In .Net the most common methods are the lock statement and the Interlocked class.

Must i abort this thread? Waiting for namedpipes. How do i do this properly?

I have another question about this same code and keeping the pipe open after the client closes it
But here i have a problem gracefully terminating my app. My main code is below. There are 2 problems. 1) I am using Thread.Abort and 2) This application doesnt actually end. I can set a breakpoint and see abort is called and step to the ending brace but the IDE is still in debug mode and the process is still alive (in process manager). How do i properly terminate this?
[STAThread]
static void Main(string[] args)
{
Thread t;
t = new Thread(new ThreadStart(ThreadStartServer));
bool hasInstance = true;
try
{
pipeStream = new NamedPipeServerStream(pipename);
hasInstance = false;
pipeStream.Close();
t.Start();
pipeStream.Dispose();
}
catch (System.IO.IOException)
{
hasInstance = true;
}
if (hasInstance)
{
clientPipeMessage(args[1]);
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
t.Abort();
}
static public void ThreadStartServer()
{
while (true)
{
using (NamedPipeServerStream pipeStream = new NamedPipeServerStream(pipename))
{
Console.WriteLine("[Server] Pipe created {0}", pipeStream.GetHashCode());
// Wait for a connection
pipeStream.WaitForConnection();
Console.WriteLine("[Server] Pipe connection established");
using (StreamReader sr = new StreamReader(pipeStream))
{
string temp;
while ((temp = sr.ReadLine()) != null)
{
Console.WriteLine("{0}: {1}", DateTime.Now, temp);
}
}
}
}
Console.WriteLine("Connection lost");
}
About Thread.Abort from MS documentation ... "Calling this method usually terminates the thread."
Furthermore "The thread is not guaranteed to abort immediately, or at all."
I suspect the WaitForConnection is blocking it from receiving the thread abort. Generally speaking, thread abort is considered Evil as who knows what state you could leave things in, etc. See here for some more help...http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation
As you suggest ... don't use Thread.Abort. Unless you have a very compelling reason why no other option will work it is a bad idea.
The problem is the blocking call to ReadLine ... so instead use StreamReader.Peek/Read to pull data from the named pipe. This will allow you to check a flag in the loop so that you can exit.
For a more complex solution you could use asynchronous I/O ... see this question for some pointers.
You need to "return" from your ThreadStartServer method when it has completed its work. If you combine this with a Join() in the Main method, the worker thread will finish gracefully. Additionally make it a BackGround thread. Here is an example (without the PipeStream):
class Prog
{
static void Main(string[] args)
{
Thread t;
t = new Thread(new ThreadStart(ThreadStartServer));
t.IsBackground = true;
try
{
t.Start();
// time consuming work here
}
catch (System.IO.IOException)
{
// from your example
}
t.Join();
}
static public void ThreadStartServer()
{
while (true)
{
int counter=0;
while (++counter < 10)
{
Console.WriteLine("working.");
// do time consuming things
Thread.Sleep(500);
}
return;
}
}
}

Categories