public class Example {
private boolean jobInProgress = false;
public void job() {
lock(this) {
if (jobInProgress) {
return;
}
jobInProgress = true;
}
// Code to execute job goes here
// ...
}
void jobCompleted() {
lock(this) {
jobInProgress = false;
}
}
}
I got this piece of code from Wikipedia and i have one thing i am not sure of.
Why jobInProgress = true; is not set inside the locked block just after the return statement? To be more explicit i will try to give a scenario:
One thread gets the lock while others are waiting
It releases the lock but before executing jobInProgress = true;, one of the waiting threads gets the lock and tests the condition which is still false.
Is this a feasible scenario or am i not getting the flow of execution right?
You are confusing yourself:
lock(this) {
if (jobInProgress) {
return;
} // <= closing brace of if
// INSIDE LOCK, OUTSIDE IF
jobInProgress = true;
} // <= closing brace of lock
I'll note that on the wiki:
public void job() {
synchronized(this) {
if (jobInProgress) {
return;
}
// INSIDE LOCK, OUTSIDE IF
jobInProgress = true;
}
// Code to execute job goes here
// ...
}
it is exactly the same!
Related
I have a while loop with a stopper:
public Myloop()
{
bool execute == true;
While (execute == true)
{
// do some stuff
if (condidtion)
{
execute == false;
}
}
}
and I'm calling in from another function after it stops:
Myloop.execute = true;
Will this be enough to restart the loop? if not, how can I restart it from another function easy way?
No, Once a while loop is done it wont start again until you run the Myloop() function again:
public void RunLoopTwice(){
MyLoop();
MyLoop();
}
public void Myloop()
{
bool execute = true;
while (execute == true)
{
// do some stuff
if (condition)
{
execute = false;
}
}
}
Also normally code is executed in a synchronous order, so only 1 piece of code is executed at the time. with async/await, Task or Thread you can make multiple pieces of code run at once. If you are using any of this, you need to make sure you properly lock pieces of code to not get any race conditions.
You are confusing == and = operators, == is for comparison while = is for assignment. Read about C# Operators.
public void Myloop()
{
bool execute = true;
while (execute == true)
{
// do some stuff
if (condition)
{
execute = false;
}
}
}
Simpler way to do this is using break since you are not returning the value of execute field. Once the condition is met, while loop will terminate.
while (true)
{
// do some stuff
if (condition) break;
}
And you call the method using Myloop(); not Myloop.execute = true;.
You can do with two flags but this code will be run on the different thread because this code will go in the infinite loop.
For Ex.
public bool doLoop = true;
public bool doProcess = true;
public void MyLoop()
{
while(doLoop)
{
while(doProcess)
{
// do some stuff
if (condition)
{
doProcess = false;
}
}
}
}
After your need is completed than make doLoop false
I am using following code.
public void runThread(){
if (System.Diagnostics.Process.GetProcessesByName("myThread").Length == 0)
{
Thread t = new Thread(new ThreadStart(go));
t.IsBackground = true;
t.Name = "myThread";
t.Start();
}
else
{
System.Diagnostics.Debug.WriteLine("myThreadis already Running.");
}
}
public void go()
{
//My work goes here
}
I am calling runThread() function many time but i want thread only start when thread is not running. How is it possible?
GetProcessesByName will not look for threads in your application but for processes in your machine. In fact there is no good way to get query for the threads in your own application (a matter aside is writing a debugger).
For what you want you could create a wrapper class for your threads in such way that you could query if they are running. Or keep track of the threads yourself by other means.
You could also consider to have a Lazy<Thread> field that will be initialized when needed, and you can query to see if the thread is till alive. After testing Lazy<Thread> is not a good idea.
Derived from Simon's answer:
private int running;
public void runThread()
{
if (Interlocked.CompareExchange(ref running, 1, 0) == 0)
{
Thread t = new Thread
(
() =>
{
try
{
go();
}
catch
{
//Without the catch any exceptions will be unhandled
//(Maybe that's what you want, maybe not*)
}
finally
{
//Regardless of exceptions, we need this to happen:
running = 0;
}
}
);
t.IsBackground = true;
t.Name = "myThread";
t.Start();
}
else
{
System.Diagnostics.Debug.WriteLine("myThreadis already Running.");
}
}
public void go()
{
//My work goes here
}
*: Gotta catch'em all
Wajid and Segey are right. You could just have a Thread field. Allow me to provide the example:
private Thread _thread;
public void runThread()
{
var thread = _thread;
//Prevent optimization from not using the local variable
Thread.MemoryBarrier();
if
(
thread == null ||
thread.ThreadState == System.Threading.ThreadState.Stopped
)
{
var newThread = new Thread(go);
newThread.IsBackground = true;
newThread.Name = "myThread";
newThread.Start();
//Prevent optimization from setting the field before calling Start
Thread.MemoryBarrier();
_thread = newThread;
}
else
{
System.Diagnostics.Debug.WriteLine("myThreadis already Running.");
}
}
public void go()
{
//My work goes here
}
Note: It is better to use the first alternative (the one derived from Simon's answer) because it is thread-safe. That is, if there are various thread calling the method runThread simultaneously there is no risk of more than one thread being created.
One easy way is that you could have a flag that indicates if it's running or not. You maybe have to use some lock if it's some conflicts.
public static bool isThreadRunning = false;
public void runThread()
{
if (!isThreadRunning)
{
Thread t = new Thread(new ThreadStart(go));
t.IsBackground = true;
t.Name = "myThread";
t.Start();
}
else
{
System.Diagnostics.Debug.WriteLine("myThreadis already Running.");
}
}
public void go()
{
isThreadRunning = true;
//My work goes here
isThreadRunning = false;
}
You can use Thread.IsAlive to check whether prevoius thread is running or not.This is to give the thread status.You can put this check before mythread.Start().
Do you create the thread only in run thread method? If it is so hold it as field of the class that holds runThread method and ask t.IsAlive.
Maybe this can help you
static bool isRunning = false;
public void RunThread(){
if (!isRunning)
{
Thread t = new Thread(()=> { go(); isRunning = true;});
t.IsBackground = true;
t.Name = "myThread";
t.Start();
}
else
{
System.Diagnostics.Debug.WriteLine("myThread is already Running.");
}
}
public void go()
{
//My work goes here
}
I need to create an method invoker that any thread (Thread B for example sake) can call, which will execute on the main executing thread (Thead A) at a specific given point in its execution.
Example usage would be as follows:
static Invoker Invoker = new Invoker();
static void ThreadA()
{
new Thread(ThreadB).Start();
Thread.Sleep(...); // Hypothetic Alpha
Invoker.Invoke(delegate { Console.WriteLine("Action"); }, true);
Console.WriteLine("Done");
Console.ReadLine();
}
static void ThreadB()
{
Thread.Sleep(...); // Hypothetic Beta
Invoker.Execute();
}
The Invoker class looks like this:
public class Invoker
{
private Queue<Action> Actions { get; set; }
public Invoker()
{
this.Actions = new Queue<Action>();
}
public void Execute()
{
while (this.Actions.Count > 0)
{
this.Actions.Dequeue()();
}
}
public void Invoke(Action action, bool block = true)
{
ManualResetEvent done = new ManualResetEvent(!block);
this.Actions.Enqueue(delegate
{
action();
if (block) done.Set();
});
if (block)
{
done.WaitOne();
}
}
}
This works fine in most cases, although it won't if, for any reason, the execution (and therefore the Set) is done before the WaitOne, in which case it will just freeze (it allows for the thread to proceed, then blocks). That could be reproduced if Alpha >> Beta.
I can use booleans and whatnot, but I'm never getting a real atomic safety here. I tried some fixes, but they wouldn't work in the case where Beta >> Alpha.
I also thought of locking around both the Invoker.Execute and Invoker.Invoke methods so that we are guaranteed that the execution does not occur between enqueing and waiting. However, the problem is that the lock also englobes the WaitOne, and therefore never finishes (deadlock).
How should I go about getting absolute atomic safety in this paradigm?
Note: It really is a requirement that I work with this design, from external dependencies. So changing design is not a real option.
EDIT: I did forget to mention that I want a blocking behaviour (based on bool block) until the delegate is executed on the Invoke call.
Use a Semaphore(Slim) instead of the ManualResetEvent.
Create a semaphore with an maximum count of 1, call WaitOne() in the calling thread, and call Release() in the delegate.
If you've already called Release(), WaitOne() should return immediately.
Make sure to Dispose() it when you're done, preferably in a using block.
If block is false, you shouldn't create it in the first place (although for SemaphoreSlim, that's not so bad).
You can use my technique:
public void BlockingInvoke(Action action)
{
volatile bool isCompleted = false;
volatile bool isWaiting = false;
ManualResetEventSlim waiter = new ManualResetEventSlim();
this.Actions.Enqueue(delegate
{
action();
isCompleted = true;
Thread.MemoryBarrier();
if (!isWaiting)
waiter.Dispose();
else
waiter.Set();
});
isWaiting = true;
Thread.MemoryBarrier();
if (!isCompleted)
waiter.Wait();
waiter.Dispose();
}
Untested
I'm answering only to show the implementation SLaks described and my solution to ensure proper and unique disposal with locks. It's open to improvement and criticism, but it actually works.
public class Invoker
{
private Queue<Action> Actions { get; set; }
public Invoker()
{
this.Actions = new Queue<Action>();
}
public void Execute()
{
while (this.Actions.Count > 0)
{
this.Actions.Dequeue()();
}
}
public void Invoke(Action action, bool block = true)
{
if (block)
{
SemaphoreSlim semaphore = new SemaphoreSlim(1);
bool disposed = false;
this.Actions.Enqueue(delegate
{
action();
semaphore.Release();
lock (semaphore)
{
semaphore.Dispose();
disposed = true;
}
});
lock (semaphore)
{
if (!disposed)
{
semaphore.Wait();
semaphore.Dispose();
}
}
}
else
{
this.Actions.Enqueue(action);
}
}
}
I have objects, they get locks. I want to test if they are locked without acquiring a lock. The idea is if I TryEnter() then i have to Exit() if true to only check the lock correctly.
Seems like a really basic question, how is it done?
What possible information can you get from knowing the lock was unlocked back when you looked at it? By the time you make a decision based on that information, the lock may be already taken.
Because the lock statement is equivalent to:
System.Threading.Monitor.Enter(x);
try {
...
}
finally {
System.Threading.Monitor.Exit(x);
}
Can you just do this?
bool ObjectWasUnlocked(object x)
{
if(System.Threading.Monitor.TryEnter(x))
{
System.Threading.Monitor.Exit(x);
return true;
}
else
{
return false;
}
}
Note that I'm naming this function "ObjectWasUnlocked" as opposed to "ObjectIsUnlocked". There is no guarantee that it will still be unlocked when the function has returned.
I was wondering the same thing while trying to audit my code for correct locking. I came up with a method using a second thread. If the lock is available to the calling thread, but unavailable to a second thread, it must be held by the first.
/// <summary>
/// Utiltity for checking if a lock has already been acquired.
/// WARNING: This test isn't actually thread-safe,
/// it's only really useful for unit tests
/// </summary>
private static bool ObjectIsAlreadyLockedByThisThread(object lockObject)
{
if (!Monitor.TryEnter(lockObject))
{
// another thread has the lock
return false;
}
Monitor.Exit(lockObject);
bool? LockAvailable = null;
var T = new Thread(() =>
{
if (Monitor.TryEnter(lockObject))
{
LockAvailable = true;
Monitor.Exit(lockObject);
}
else
{
LockAvailable = false;
}
});
T.Start();
T.Join();
return !LockAvailable.Value;
}
// Tests:
public static void TestLockedByThisThread()
{
object MyLock = new object();
lock (MyLock)
{
bool WasLocked = ObjectIsAlreadyLockedByThisThread(MyLock);
Debug.WriteLine(WasLocked); // prints "True"
}
}
public static void TestLockedByOtherThread()
{
object MyLock = new object();
var T = new Thread(() =>
{
lock (MyLock)
{
Thread.Sleep(TimeSpan.FromSeconds(2));
}
});
T.Start();
Thread.Sleep(TimeSpan.FromSeconds(1));
bool WasLocked = ObjectIsAlreadyLockedByThisThread(MyLock);
T.Join();
Debug.WriteLine(WasLocked); // prints "False"
}
public static void TestNotLocked()
{
object MyLock = new object();
bool WasLocked = ObjectIsAlreadyLockedByThisThread(MyLock);
Debug.WriteLine(WasLocked); // prints "False"
}
I wouldn't use this in production code - there's a race condition that could blow up. However, my unit tests are mostly single threaded, so this was useful.
Here is a related question
Checking whether the current thread owns a lock
The conclusion there was 'you can't'
I wrote a multithreaded application for .NET and in a very important portion of code I have the following:
public class ContainerClass {
private object list_lock;
private ArrayList list;
private object init_lock = new object();
private ThreadClass thread;
public void Start() {
lock(init_lock) {
if (thread == null) {
thread = new ThreadClass();
...
}
}
}
public void Stop() {
lock(init_lock) {
if (thread != null) {
thread.processList(0);
thread.finish();
thread.waitUntilFinished();
thread = null;
} else {
throw new ApplicationException("Assertion failed - already stopped.");
}
...
}
}
private class ThreadedClass {
private ContainerClass container;
private Thread thread;
private bool finished;
private bool actually_finished;
public ThreadedClass(ContainerClass container) {
this.container = container;
thread = new Thread(run);
thread.IsBackground = true;
thread.Start();
}
private void run() {
bool local_finished = false;
while (!local_finished) {
ArrayList to_process = null;
lock (container.list_lock) {
if (container.list.Count > 0) {
to_process = new ArrayList();
to_process.AddRange(container.list);
}
}
if (to_process == null) {
// Nothing to process so wait
lock (this) {
if (!finished) {
try {
Monitor.Wait(this);
} catch (ThreadInterruptedException) {
}
}
}
} else if (to_process.Count > 0) {
// Something to process, so go ahead and process the journals,
int sz = to_process.Count;
// For all elements
for (int i = 0; i < sz; ++i) {
// Pick the lowest element to process
object obj = to_process[i];
try {
// process the element...
...
} catch (IOException e) {
...
// If there is an error processing the best thing to do is finish
lock (this) {
finished = true;
}
}
}
}
lock (this) {
local_finished = finished;
// Remove the elements that we have just processed.
if (to_process != null) {
lock (container.list_lock) {
int sz = to_process.Count;
for (int i = 0; i < sz; ++i) {
container.list.RemoveAt(0);
}
}
}
// Notify any threads waiting
Monitor.PulseAll(this);
}
}
lock (this) {
actually_finished = true;
Monitor.PulseAll(this);
}
}
public void waitUntilFinished() {
lock (this) {
try {
while (!actually_finished) {
Monitor.Wait(this);
}
} catch (ThreadInterruptedException e) {
throw new ApplicationException("Interrupted: " + e.Message);
}
}
}
public void processList(int until_size) {
lock (this) {
Monitor.PulseAll(this);
int sz;
lock (container.list_lock) {
sz = container.list.Count;
}
// Wait until the sz is smaller than 'until_size'
while (sz > until_size) {
try {
Monitor.Wait(this);
} catch (ThreadInterruptedException ) {
}
lock (container.list_lock) {
sz = container.list.Count;
}
}
}
}
}
}
As you can see, the thread waits until the collection is empty but it seems that the synchronization clashes forbids the thread to enter at the point (the only one in the whole code) where an element is removed from the collection list in the ContainerClass.
This clash provokes the code to never return and the application to continue running if the method processList is called with the value of until_size of 0.
I beg any better developer than me (and I guess there are a lot out there) to help me fixing this small piece of code, since I really can't understand why the list isn't decremented...
Thank you very much from the bottom of my heart.
PS. I would like to underline that the code works perfectly for all the time: the only situation in which it brakes it's when calling thread.processList(0) from ContainerClass.Stop().
Could the problem be that you are locking the ThreadClass object itself rather than a synchronizing object?
Try adding another private variable to lock on:
private static readonly object lockObject = new object()
and replace all the calls of lock(this) with lock(lockObject)
MSDN clearly advises against what your doing:
In general, avoid locking on a public
type, or instances beyond your code's
control. The common constructs lock
(this), lock (typeof (MyType)), and
lock ("myLock") violate this
guideline:
lock (this) is a problem if the instance can be accessed publicly.
Edit:
I think I see a deadlock condition. If you call run() when there are no objects to process, or you get to no objects to process, you lock(this), then call Monitor.Wait(this) and the thread waits:
if (to_process == null) {
// Nothing to process so wait
lock (this) { /* nothing's going to get this lock again until Monitor.PulseAll(this) is called from somewhere */
if (!finished) {
try {
Monitor.Wait(this); /* thread is waiting for Pulse(this) or PulseAll(this) */
} catch (ThreadInterruptedException) {
}
}
}
}
If you are in this condition when you call Container.Stop(), when ThreadProcess.processList(int) is called, you call lock(this) again, which can't enter the section because the run() method still has the lock:
lock (this) { /* run still holds this lock, waiting for PulseAll(this) to be called */
Monitor.PulseAll(this); /* this isn't called so run() never continues */
int sz;
lock (container.list_lock) {
sz = container.list.Count;
}
So, Monitor.PulseAll() can't be called to free the waiting thread in the run() method to exit the lock(this) area, so they are deadlocked waiting on each other. Right?
I think you should try to explain better what you actually want to achieve.
public void processList(int until_size) {
lock (this) {
Monitor.PulseAll(this);
This looks very strange as you should call the Monitor.Pulse when changing the lock state and not when beginning with locking.
Where are you creating the worker threads - this section is not clear as I see only Thread.Start()?
Btw I would advise you to look at PowerCollections - maybe you find what you need there.