Thread.Abort() and delay after finally - c#

When Thread.Abort() is called, and that thread is executing finally block, then thread won't abort until finally block is finished. But, as i see, ThreadAbortException is generated not right after the end of finally block, but after some delay:
private static volatile int val1 = 0;
public static void Func1()
{
try
{
}
finally
{
Thread.Sleep(5000);
}
//Func2();
while (true)
val1++;
}
public static void Main()
{
var thread = new Thread(Func1);
thread.Start();
Thread.Sleep(1000);
thread.Abort();
thread.Join();
Console.WriteLine(val1); // val1 is non-zero!
}
In this example, val1 at the end of Main() will be non-zero. Why does it happen?
If i uncomment call to Func2() (Func2 is any method, possibly empty), output for val1 will show "0". Why does adding of method affect point of thread abortion?

In this case it could be usefull to surround the increment with a lock. The lock controlls the access on that member. The Abort method just notify the thread "Hey, you can stop now" but it does not kill the Thread. So the thread can be alive for a few moments after the Abort. Accessing the lock the thread checks if it got aborted and kills it self if needed.
Here is your example code edited
using System;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
private static volatile int val1 = 0;
static Object Locker = new Object();
public static void Func1()
{
try
{
}
finally
{
Thread.Sleep(5000);
}
//Func2();
while (true)
{
//Lock the access to the member
lock (Locker)
val1++;
}
}
public static void Main()
{
var thread = new Thread(Func1);
thread.Start();
Thread.Sleep(1000);
//Not needed. Just to make sure
lock (Locker)
{
thread.Abort();
thread.Join();
}
Console.WriteLine(val1); // val1 is non-zero!
// Now it is zero
Console.ReadLine();
}
}
}
Sorry for late answer

Related

How to break out a loop contains only a constrained execution region (CER)

I'm using a constrained execution region (CER) to protect the section of code within a while loop of a thread:
private static void MyThreadFunc()
{
try {
...
while (true)
{
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally
{
// do something not to be aborted
}
Thread.Sleep(1); // allow while loop to be broken out
}
}
catch (ThreadAbortException e)
{
// handle the exception
}
}
The problem is if I do not introduce the Thread.Sleep(1) statement at the end of the while loop, any attempt to call Thread.Abort() on the thread hangs. Is there any better method to abort the thread without using the Thread.Sleep() function?
I don't know why you need to abort the thread manually as CLR will do it once it's completed or use Thread.Join to wait until it terminates. But you can make use of the ManualResetEvent to abort it gracefully.
I have made few changes in the code by replacing the while(true) with the ManualResetEvent
class ThreadManager
{
private ManualResetEvent shutdown = new ManualResetEvent(false);
private Thread thread;
public void start ()
{
thread = new Thread(MyThreadFunc);
thread.Name = "MyThreadFunc";
thread.IsBackground = true;
thread.Start();
}
public void Stop ()
{
shutdown.Set();
if (!thread.Join(2000)) //2 sec to stop
{
thread.Abort();
}
}
void MyThreadFunc ()
{
while (!shutdown.WaitOne(0))
{
// call with the work you need to do
try {
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally
{
// do something not to be aborted
}
}
catch (ThreadAbortException e)
{
// handle the exception
}
}
}
}

How come this code does not deadlock?

Shouldn't the Log method block?
namespace Sandbox {
class Program {
static void Main(string[] args) {
var log = new Logger();
lock (log) {
log.Log("Hello World!");
}
}
}
public class Logger {
public void Log(string message) {
lock (this) {
Console.WriteLine(message);
}
}
}
}
The same thread is acquiring the same lock twice. This works because .NET supports so-called recursive locks (aka reentrant mutexes).
If a resource is locked by a thread, that thread is allowed in, even if it already owns a lock on it. The same is true for this
Object obj = new Object();
lock(obj) {
lock(obj) {
foo();
}
}
Would lock out if you couldn't get through by virtue of being the same thread.
Simple - you are running in a single thread.

Dead lock in Multithreading

I was trying to create an example for deadlock. I tried the following code. But instead of creating deadlock, it worked like charm. Help me in understanding why it didn't create a deadlock. What change in this code would create a deadlock?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ReferenceTypes
{
class DeadLockExample
{
static int a;
static int b;
public static void Main(string[] args)
{
DeadLockExample.a = 20;
DeadLockExample.b = 30;
DeadLockExample d = new DeadLockExample();
Thread tA = new Thread(new ThreadStart(d.MethodA));
Thread tB = new Thread(new ThreadStart(d.MethodB));
tA.Start();
tB.Start();
Console.ReadLine();
}
private void MethodA()
{
lock (this)
{
Console.WriteLine(a);
Thread.Sleep(1000);
Console.WriteLine(b);
}
}
private void MethodB()
{
lock (this)
{
Console.WriteLine(b);
Thread.Sleep(1000);
Console.WriteLine(a);
}
}
}
}
As everyone else has said, two locks acquired in different orders, so that each is waiting on the other. I also changed one of the Sleep lengths to ensure a high probability of the deadlock occurring.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ReferenceTypes
{
class DeadLockExample
{
static int a;
static int b;
static object lockedObjA = new object();
static object lockedObjB = new object();
public static void Main(string[] args)
{
DeadLockExample.a = 20;
DeadLockExample.b = 30;
DeadLockExample d = new DeadLockExample();
Thread tA = new Thread(new ThreadStart(d.MethodA));
Thread tB = new Thread(new ThreadStart(d.MethodB));
tA.Start();
tB.Start();
Console.ReadLine();
}
private void MethodA()
{
lock (DeadLockExample.lockedObjA)
{
Console.WriteLine(a);
Thread.Sleep(1200);
lock (DeadLockExample.lockedObjB) {
Console.WriteLine(b);
}
}
}
private void MethodB()
{
lock (DeadLockExample.lockedObjB)
{
Console.WriteLine(b);
Thread.Sleep(1000);
lock (DeadLockExample.lockedObjA) {
Console.WriteLine(a);
}
}
}
}
}
2 locks, 2 threads.
Thread A takes lock A, sleeps and then tries to take lock B. Thread B takes lock B, sleeps and then tries to take lock A, equals a Deadlock.
[Thread A has to sleep long enough so that thread B takes lock B before thread A attempts to acquire it]
Here are 3 different ways you can cause a deadlock. This list is not exhaustive.
Call a blocking method from within a lock section.
In this example thread A acquires a lock and then immediately calls a blocking method while at the same time thread B attempts to acquire the same lock, but gets hung because thread A is waiting for thread B to signal the event before it will release the lock.
public class Example
{
ManualResetEvent m_Event = new ManualResetEvent(false);
void ThreadA()
{
lock (this)
{
m_Event.WaitOne();
}
}
void ThreadB()
{
lock (this)
{
m_Event.Set();
}
}
}
Acquire two locks out of order.
No explanation is needed here since this is a well known problem.
public class Example
{
private object m_LockObjectA = new object();
private object m_LockObjectB = new Object();
void ThreadA()
{
lock (m_LockObjectA) lock (m_LockObjectB) { }
}
void ThreadB()
{
lock (m_LockObjectB) lock (m_LockObjectA) { }
}
}
The lock-free deadlock.
This is one my favorite illustrations of a deadlock because no lock or blocking method is involved. The subtlety of the problem is enough to confound even those who are familiar with threading. The issue here is related to the absence of memory barriers. Thread A waits for thread B to set the signal flag while at the same time thread B waits for thread A to reset it all the while neither thread is seeing the changes the other is making because the compiler, JIT, and hardware are free to optimize the reads and writes of the flag in manner that is non-intuitive.
public class Example
{
private bool m_Signal = false;
void ThreadA()
{
while (!m_Signal);
m_Signal = false;
}
void ThreadB()
{
m_Signal = true;
while (m_Signal);
}
}
From Wikipedia -
A deadlock is a situation wherein two
or more competing actions are each
waiting for the other to finish, and
thus neither ever does.
You don't fulfil this requirement with your code above - there's never a point where both thread A and thread B are waiting on each other to complete.

How to pause/suspend a thread then continue it?

I am making an application in C# which uses a winform as the GUI and a separate thread which is running in the background automatically changing things. Ex:
public void Run()
{
while(true)
{
printMessageOnGui("Hey");
Thread.Sleep(2000);
// Do more work
}
}
How would I make it pause anywhere in the loop, because one iteration of the loop takes around 30 seconds. So I wouldn't want to pause it after its done one loop, I want to pause it on time.
var mrse = new ManualResetEvent(false);
public void Run()
{
while (true)
{
mrse.WaitOne();
printMessageOnGui("Hey");
Thread.Sleep(2000); . .
}
}
public void Resume() => mrse.Set();
public void Pause() => mrse.Reset();
You should do this via a ManualResetEvent.
ManualResetEvent mre = new ManualResetEvent();
mre.WaitOne(); // This will wait
On another thread, obviously you'll need a reference to the mre
mre.Set(); // Tells the other thread to go again
A full example which will print some text, wait for another thread to do something and then resume:
class Program
{
private static ManualResetEvent mre = new ManualResetEvent(false);
static void Main(string[] args)
{
Thread t = new Thread(new ThreadStart(SleepAndSet));
t.Start();
Console.WriteLine("Waiting");
mre.WaitOne();
Console.WriteLine("Resuming");
}
public static void SleepAndSet()
{
Thread.Sleep(2000);
mre.Set();
}
}
You can pause a thread by calling thread.Suspend but that is deprecated. I would take a look at autoresetevent for performing your synchronization.

How can I replace this semaphore with a monitor?

In previous question of mine, someone had meantioned that using Semaphores were expensive in C# compared to using a monitor. So I ask this, how can I replace the semaphore in this code with a monitor?
I need function1 to return its value after function2 (in a separate thread) has been completed. I had replaced the Semaphore.WaitOne with a Monitor.Wait and the Semaphore.Release with a Monitor.PulseAll but the PulseAll was being triggered before the Wait causing the program to hang. Any idea how to avoid that race condition?
Semaphore semaphore = new Semaphore(0,1);
byte b;
public byte Function1()
{
// new thread starting in Function2;
semaphore.WaitOne();
return b;
}
public void Function2()
{
// do some thing
b = 0;
semaphore.Release();
}
You can do this with a WaitHandle instead of a Semaphore. This would be the simplest alternative, and perform better than a Semaphore:
ManualResetEvent manualResetEvent = new ManualResetEvent(false);
byte b;
public byte Function1()
{
// new thread starting in Function2;
manualResetEvent.WaitOne();
return b;
}
public void Function2()
{
// do some thing
b = 0;
manualResetEvent.Set();
}
#Reed provided an elegant solution if you need to wait for multiple threads.
You might not want to use Monitor fro this.
As #Reed pointed out, an event would suffice and would provide the cleanest and most understandable solution that matches the requirements of your code.
The overhead of using real operating system sync primitives will most probably not matter in your case and using e.g. Monitor would provide only diminishing returns at the cost of much higher complexity.
With that said, here is an implementation using Monitor and signaling.
You can use a bool flag - guarded by the lock - to indicate that you have finished and avoid waiting in that case. (A)
If you really start a new thread within Function2() where the comments indicate and use lock() around both WaitOne() and Release(), you do not need the flag at all. (B)
A, using a flag:
class Program
{
static object syncRoot = new object();
//lock implies a membar, no need for volatile here.
static bool finished = false;
static byte b;
public static byte Function1()
{
lock (syncRoot)
{
//Wait only if F2 has not finished yet.
if (!finished)
{
Monitor.Wait(syncRoot);
}
}
return b;
}
static public void Function2()
{
// do some thing
b = 1;
lock (syncRoot)
{
finished = true;
Monitor.Pulse(syncRoot);
}
}
static void Main(string[] args)
{
new Thread(Function2).Start();
Console.WriteLine(Function1());
}
}
B, starting a thread from Function1:
class Program
{
static object syncRoot = new object();
static byte b;
public static byte Function1()
{
lock (syncRoot)
{
// new thread starting in Function2;
new Thread(Function2).Start();
Monitor.Wait(syncRoot);
}
return b;
}
static public void Function2()
{
// do some thing
b = 1;
//We need to take the lock here as well
lock (syncRoot)
{
Monitor.Pulse(syncRoot);
}
}
static void Main(string[] args)
{
Console.WriteLine(Function1());
}
}

Categories