I have the following code in my console application:
if (Count % 11 >= 5)
{
GrabberTask = GrabberTask.ContinueWit(Grabber.ExtractSources);
}
The if clause is inside a loop with a counter. I want to know what happens if the if evaluates to true for a second time before the GrabberTask starts for the first time. Is there any better way to keep doing the same Task when the if condition evaluates to true. I am extracting the image sources from a webpage and storing them in a LinkedList. Sometimes I am getting duplicate links being added to the LinkedList from two different Tasks. How to prevent that?
Each time you provide a continuation, the whole continuation will be executed.
What you need is to implement some kind of thread synchronization to avoid more than a thread execute a given operation against some resource.
The simplest one is the lock statement:
public class Test
{
private static readonly object _syncLock = new object();
public void MyMethod()
{
lock(_syncLock)
{
// No more than a thread will be able to work within this
// protected code block. Others will be awaiting/blocked until
// the thread that acquired the lock leaves this code block
}
}
}
Now, if you perform many continuations in some time interval that might need to execute the same thing, no more than a continuation will be able to be executed at once.
Related
I am currently building a multi-threaded software (in C#), and I am not sure about my solution for a problem.
// isLocked is initialized at earlier stage
if (!isLocked)
{
isLocked = true;
// More code here
}
I know that the condition check is atomic, but i think its possible that another thread will enter the if block before 'isLocked' is assigned the 'true' value (thus creating an unwanted situation).
In Java, i could use AtomicBoolean's method 'compareAndSet' which is atomic, but C#'s equivalent 'CompareExchange' is not atmoic.
I tried using a bool in addition to the lock so that if the "locked" code is already being executed, other threads will bypass it. Is this a good way to do that, or is there a better way?
Object myLock = new object();
bool free = false;
bool isLocked= actorsLocks[i];// Some Data structure
if (!isLocked)
{
lock(mylock)
{
if (!isLocked)
{
isLocked= true;
free = true;
}
}
}
if(free)
{
// actual method code here...
}
Is there a more efficient solution?
Thank you very much in advance.
In Java, i could use AtomicBoolean's method 'compareAndSet' which is
atomic, but C#'s equivalent 'CompareExchange' is not atmoic.
...Uh... yeah it is. Otherwise it would be completely useless.
https://msdn.microsoft.com/en-us/library/801kt583(v=vs.110).aspx#Anchor_2
If comparand and the value in location1 are equal, then value is
stored in location1. Otherwise, no operation is performed. The compare
and exchange operations are performed as an atomic operation. The
return value of CompareExchange is the original value in location1,
whether or not the exchange takes place.
Your solution is close. Make sure your lock object and all variables it protects are accessible by all threads. It won't do you any good to lock a locally-declared object. For example, myLock could be a class data member. It definitely should not be declared in the function. Same thing goes for isLocked.
class C
{
int[] m_actorsLocks; // *See below
...
void WorkerFunction(int threadIndex)
{
if (CompareExchange(ref m_actorsLocks[threadIndex], 1, 0) == 0) // cmpxchg returns old value. If old value was false, it means WE locked it!
{
// do work
// use cmpxchg to free the lock
CompareExchange(ref m_actorsLocks[threadIndex], 0, 1)
// I do this simply because I don't understand how C# caches outgoing writes
// could possibly do m_actorsLocks[threadIndex] = 0; surrounded by Interlocked.MemoryBarrier()
}
else
{
// Threads who didn't get the lock come here...
// If I understand what you're trying to do, you don't want the other threads to wait if they didn't get the lock.
// So you probably wouldn't need this else clause...
}
}
...
};
*If you store your locks in an array, you'll experience false sharing. Since arrays are stored contiguously, your locks will be on the same cache line... you would have the same performance as if you used 1 lock for everything. The grungy way to deal with this is to pad out your array. For example:
// If I want 4 locks
int[] m_actorsLocks = new int[32];
// Now i only use index 0, 8, 16, and 24. The rest are just padding.
It's kinda messy and requires knowlege of your architecture... Better do some research on this one and maybe ask a seperate question.
All you need in C# is:
object theLock = new Object();
lock(theLock)
{
// Lock is yours, enjoy
}
If you want to both attempt to acquire the lock and find out whether you acquired it, in one atomic operation, use Monitor.TryEnter(object).
Monitor.TryEnter returns true if the lock is acquired, false if it isn't. Only execute the "locked" code if TryEnter returns true.
public class SomeClassThatMultipleThreadsAccess
{
private readonly object _lockObject = new object();
public void MethodThatGetsCalledConcurrently()
{
if(Monitor.TryEnter(_lockObject))
{
try
{
// only one thread at a time can execute this in
// one instance of the class.
// If _lockObject is static then only one thread at
// a time can execute this across all instances of
// the class.
}
finally // very important - if we don't exit then nothing else can enter.
{
Monitor.Exit(_lockObject);
}
}
}
}
Note that the object used for locking cannot be declared in the same scope in which it is used.
These both do nothing:
var lockObject = new object();
if(Monitor.TryEnter(lockObject))
var lockObject = new object();
lock(lockObject)
{
because each thread will create a different object, so each thread will immediately acquire the lock. It won't prevent concurrent access to anything ever. There must be one object on which multiple threads attempt to acquire a lock.
In few words: you're asking for trouble. Don't do that.
In more details, there are many factors you underestimate:
CPU conveyor optimization. This means that without proper "do not touch, multiple threads accessing" mark your CPU can modify execution order. And this may do very unexpected things that're absolutely legit in terms of single thread but can ruin your synchronization logic.
Compiler optimization. This can eliminate entire block of code according to Boolean value (and compiler has no idea the bool can be changed by another thread).
False sharing. This is more advanced thing and it can't change your program behavior. However, it can cause significant performance degradation because you read&write your hand-made locks at continuous array (that ruins core-level caches, fastest ones).
This is what can be named right out of the head. If think more, we can find more cons against hand-made thread sync mechanics. So, multithreading is like encryption: do not try to reinvent it, you're dangerously low-informed and would be cracked in minutes or even seconds.
You are right: the read of the bool is atomic but several threads can read atomically the bool and enter the 'if' block before the flag becomes false.
To do what you want (one thread only enters the 'if' block without blocking other threads) you can use kind of :
private long _n = 0;
......
if (Interlocked.Exchange(ref _n, 1) == 0)
{
// More code here, only one thread at a time.
// Be carefull with exceptions.
Interlocked.Exchange(ref _n, 0); // Reset the flag for next running.
}
The Interlocked.Exchange is an atomic read&write: it will block all the threads, except one which will read '_n=0' and write '_n=1' as an atomic operation. The other threads will got 1 immediatly after the interlocked statment returns and they do not enter the block.
I have a question about locking and whether I'm doing it right.
In a class, I have a static lock-object which is used in several methods, assume access modifiers are set appropriately, I won't list them to keep it concise.
class Foo
{
static readonly object MyLock = new object();
void MethodOne()
{
lock(MyLock) {
// Dostuff
}
}
void MethodTwo()
{
lock(MyLock) {
// Dostuff
}
}
}
Now, the way I understand it, a lock guarantees only one thread at a time will be able to grab it and get into the DoStuff() part of one method.
But is it possible for the same thread to call MethodOne() and MethodTwo() at the same time? Meaning that he uses the lock he has gotten for both methods?
My intended functionality is that every method in this class can only be called by a single thread while no other method in this class is currently executing.
The underlying usage is a database class for which I only want a single entry and exit point. It uses SQL Compact, so if I attempt to read protected data I get all sorts of memory errors.
Let me just add that every once and a while a memory exception on the database occurs and I don't know where it's coming from. I thought it was because of one thread doing multiple things with the database before completing things, but this code seems to work like it should.
But is it possible for the same thread to call MethodOne() and MethodTwo() at the same time?
No. Same thread can't call both the methods at same time whether lock is used on not.
lock(MyLock)
It can be understood as following:
MyLock object has a key to enter itself. a thread (say t1) who accesses it first gets it. Other threads will have to wait until t1 releases it. But t1 can call another method and will pass this line as it already has acquired lock.
But, at the same time calling both the methods ... not possible by single thread. Not in current programming world.
the way I understand it, a lock guarantees only one thread at a time will be able to grab it and get into the DoStuff() part of one method.
Your understanding is correct but remember that threads are used to do parallel execution but the execution within a thread is always sequential.
But is it possible for the same thread to call MethodOne() and MethodTwo() at the same time?
It is not possible for a single thread to call anything at the same time.
In a multithreaded application, this can happen - the methods can be called simultaneously, but the // Dostuff sections can only be accessed sequentially.
My intended functionality is that every method in this class can only be called by a single thread while no other method in this class is currently executing.
Then don't use additional threads in your application - just have the main one and don't use extra ones.
The only way for a thread inside Dostuff of the running MethodOne to call MethodTwo is for the Dostuff of the MethodOne to make the call to MethodTwo. If this is not happening (i.e. methods in your "mutually locked" group do not call each other), you are safe.
There are a few things that can be answered here.
But is it possible for the same thread to call MethodOne() and
MethodTwo() at the same time? Meaning that he uses the lock he has
gotten for both methods?
No, a thread has a single program counter, its either in MethodOne() or in MethodTwo(). If however you have something as follows,
public void MethodThree()
{
lock (MyLock)
{
MethodOne();
MethodTwo();
}
}
That will also work, a thread can acquire the same lock multiple times. Just watch out for what you're doing as you can easily get into a deadlock as the code becomes more complex.
My intended functionality is that every method in this class can only
be called by a single thread while no other method in this class is
currently executing.
The underlying usage is a database class for which I only want a
single entry and exit point. It uses SQL Compact, so if I attempt to
read protected data I get all sorts of memory errors.
I don't really understand why, but if you think you need to do this because you're using SqlCompact, you're wrong. You should be using transactions which are supported on SqlCe.
E.g.
using (var connection = new SqlCeConnection())
using (var command = new SqlCeCommand())
using (var transaction = conn.BeginTransaction())
{
command.Transaction = transaction;
command.ExecuteNonQuery();
transaction.Commit();
}
In the piece of code that I'm working on, another developer's library fires off one of my object's methods on regular, scheduled intervals. I've run into problems where the previous call into my object's method has not completed at the time another interval is reached and a second call is made into my method to execute again - the two threads then end up stepping on each other. I'd like to be able to wrap the method's implementation with a check to see whether it is in the middle of processing and skip over the block if so.
A lock is similar to what I want, but doesn't quite cover it because a lock will block and the call into my method will pick up as soon as the previous instance releases the lock. That's not what I want to happen because I could potentially end up with a large number of these calls backed up and all waiting to process one by one. Instead, I'd like something similar to a lock, but without the block so that execution will continue after the block of code that would normally be surrounded by the lock.
What I came up with was a counter to be used with Interlocked.Increment and Interlocked.Decrement to allow me to use a simple if statement to determine whether execution on the method should continue.
public class Processor
{
private long _numberOfThreadsRunning = 0;
public void PerformProcessing()
{
long currentThreadNumber Interlocked.Increment(ref _numberOfThreadsRunning);
if(currentThreadNumber == 1)
{
// Do something...
}
Interlocked.Decrement(ref _numberOfThreadsRunning);
}
}
I feel like I'm overthinking this and there may be a simpler solution out there.
You could call Monitor.TryEnter and just continue if it returns false.
public class Processor
{
private readonly object lockObject = new object();
public void PerformProcessing()
{
if (Monitor.TryEnter(lockObject) == true)
{
try
{
// Do something...
}
finally
{
Monitor.Exit(lockObject);
}
}
}
}
How about adding a flag to the object. In the method set the flag true to indicated the method is being executed. At the very end of the method, reset it to false. Then you could check the status of the flag to know if the method can be called.
I need to design a thread-safe logger. My logger must have a Log() method that simply queues a text to be logged. Also a logger must be lock-free - so that other thread can log messages without locking the logger. I need to design a worker thread that must wait
for some synchronization event and then log all messages from the queue using standard .NET logging (that is not thread-safe). So what i am interested in is synchronization of worker thread - and Log function. Below is a sketch of the class that i designed. I think I must use Monitor.Wait/Pulse here or any other means to suspend and resume worker thread. I don;t want to spend CPU cycles when there is no job for logger.
Let me put it another way - I want to design a logger that will not block a caller threads that use it. I have a high performance system - and that is a requirement.
class MyLogger
{
// This is a lockfree queue - threads can directly enqueue and dequeue
private LockFreeQueue<String> _logQueue;
// worker thread
Thread _workerThread;
bool _IsRunning = true;
// this function is used by other threads to queue log messages
public void Log(String text)
{
_logQueue.Enqueue(text);
}
// this is worker thread function
private void ThreadRoutine()
{
while(IsRunning)
{
// do something here
}
}
}
"lock-free"does not mean that threads won't block each other. It means that they block each other through very efficient but also very tricky mechanisms. Only needed for very high performance scenarios and even the experts get it wrong (a lot).
Best advice: forget "lock-free"and just use a "thread-safe" queue.
I would recommend the "Blocking Queue" from this page.
And it's a matter of choice to include the ThreadRoutine (the Consumer) in the class itself.
To the second part of your question, it depends on what "some synchronization event" exactly is. If you are going to use a Method call, then let that start a one-shot thread. If you want to wait on a Semaphore than don't use Monitor and Pulse. They are not reliable here. Use an AutoResetEvent/ManualResetEvent.
How to surface that depends on how you want to use it.
Your basic ingredients should look like this:
class Logger
{
private AutoResetEvent _waitEvent = new AutoResetEvent(false);
private object _locker = new object();
private bool _isRunning = true;
public void Log(string msg)
{
lock(_locker) { _queue.Enqueue(msg); }
}
public void FlushQueue()
{
_waitEvent.Set();
}
private void WorkerProc(object state)
{
while (_isRunning)
{
_waitEvent.WaitOne();
// process queue,
// ***
while(true)
{
string s = null;
lock(_locker)
{
if (_queue.IsEmpty)
break;
s = _queue.Dequeu();
}
if (s != null)
// process s
}
}
}
}
Part of the discussion seems to be what to do when processing the Queue (marked ***). You can lock the Queue and process all items, during which adding of new entries will be blocked (longer), or lock and retrieve entries one by one and only lock (very) shortly each time. I've adde that last scenario.
A summary: You don't want a Lock-Free solution but a Block-Free one. Block-Free doesn't exist, you will have to settle for something that blocks as little as possible. The last iteration of mys sample (incomplete) show how to only lock around the Enqueue and Dequeue calls. I think that will be fast enough.
Has your profiler shown you that you are experiencing a large overhead by using a simple lock statement? Lock-free programming is very hard to get right, and if you really need it I would suggest taking something existing from a reliable source.
It's not hard to make this lock-free if you have atomic operations. Take a singly linked list; you just need the head pointer.
Log function:
1. Locally prepare the log item (node with logging string).
2. Set the local node's next pointer to head.
3. ATOMIC: Compare head with local node's next, if equal, replace head with address of local node.
4. If the operation failed, repeat from step 2, otherwise, the item is in the "queue".
Worker:
1. Copy head locally.
2. ATOMIC: Compare head with local one, if equal, replace head with NULL.
3. If the operation failed, repeat from step 1.
4. If it succeeded, process the items; which are now local and out of the "queue".
I am working on a small project where I need to make two asynchronous calls right after another.
My code looks something like this:
AsynchronousCall1();
AsynchronousCall2();
The problem I'm having is that both calls take anywhere from one to two seconds to execute and I never know which one will finish last. What I'm looking for is a way to determine who finishes last. If Call1() finishes last, I do one thing. If Call2() finishes last, I do another thing.
This is a simple example of using a lock to ensure that only one thread can enter a piece of code. But it's a general example, which may or may not be best for your application. Add some details to your question to help us find what you're looking for.
void AsynchronousCall1()
{
// do some work
Done("1");
}
void AsynchronousCall2()
{
// do some work
Done("2");
}
readonly object _exclusiveAccess = new object();
volatile bool _alreadyDone = false;
void Done(string who)
{
lock (_exclusiveAccess)
{
if (_alreadyDone)
return;
_alreadyDone = true;
Console.WriteLine(who + " was here first");
}
}
I believe there is a method that is a member of the Thread class to check on a specific thread and determine its status. The other option would be to use a BackgroundWorker instead, as that would allow you to spell out what happens when that thread is finished, by creating seperate methods.
The "thread-unsafe" option would be to use a class variable, and at the end of each thread if it isn't locked / already have the other thread's value, don't set it. Otherwise set it.
Then when in your main method, after the call to wait for all threads to finish, test the class variable.
That will give you your answer as to which thread finished first.
You can do this with two ManualResetEvent objects. The idea is to have the main thread initialize both to unsignaled and then call the asynchronous methods. The main thread then does a WaitAny on both objects. When AsynchronousCall1 completes, it signals one of the objects. When AsynchronousCall2 completes, it signals the other. Here's code:
ManualResetEvent Event1 = new ManualResetEvent(false);
ManualResetEvent Event2 = new ManualResetEvent(false);
void SomeMethod()
{
WaitHandle[] handles = {Event1, Event2};
AsynchronousCall1();
AsynchronousCall2();
int index = WaitHandle.WaitAny(handles);
// if index == 0, then Event1 was signaled.
// if index == 1, then Event2 was signaled.
}
void AsyncProc1()
{
// does its thing and then
Event1.Signal();
}
void AsyncProc2()
{
// does its thing and then
Event2.Signal();
}
There are a couple of caveats here. If both asynchronous methods finish before the call to WaitAny, it will be impossible to say which completed first. Also, if both methods complete very close to one another (i.e. call 1 completes, then call 2 completes before the main thread's wait is released), it's impossible to say which one finished first.
You may want to check out the Blackboard design pattern: http://chat.carleton.ca/~narthorn/project/patterns/BlackboardPattern-display.html. That pattern sets up a common data store and then lets agents (who know nothing about one another -- in this case, your async calls) report their results in that common location. Your blackboard's 'supervisor' would then be aware of which call finished first and could direct your program accordingly.