I am using .net 2.0.
language:c#
I have situation where I need to lock the condition of IF block.
Given below is the simplified code of what I am trying to achieve.
Public static readyonly object _obj=new object();
if(
lock(_obj)
{
//if conditition in form of expression
}
)
Actually the condition of if block is a call to another server. So I need to make it thread safe.
Is the above flow correct? or there is someother way by which I can achieve that? or I have to lock the entire if block
The lock statement is a keyword and not a method. It does not return anything therefore the above implementation is an incorrect one. There are some typos in your question as well.
public static readonly object _obj = new object();
void Main()
{
// Any other thread is blocked from acquiring the lock and waits until the lock is released.
lock (_obj)
{
// Perform "Safe" Work Here
}
}
If you want more information on how a lock works please reference the Microsoft documentation located here.
Related
I am new to multi thread programming, yet I am studying a big project by someone else. In the code he has a singleton class and it has some public member variable and a member mutex. He used this singleton in different threads like:
singleton::instance()->mutex.lock();
singleton::instance()->value = getval();
singleton::instance()->mutex.release();
Is this the safe way to do it?
If not what is the proper way of read/write the value in singleton?
No it is not safe to do so.
The problem is that the mutex is handed out to the user. There is no guarantee that this lock will be released. For example, what happens if getval() would throw an exception ?
The proper way to do so would be to embed mutex use inside the API of your singleton. For example:
void singleton::setvalue(int val) { // example supposing value is an int
std::lock_guard<std::mutex> mylck (mutex);
value = val;
}
In this example, a local std::lock_guard is used. This object locks the mutex and unlocks it on destruction. This makes sure that in any case the mutex will be unlocked, whenever function returns and even if an exception would be thrown.
Note: If all you are doing is getting a variable like return variable; then it is safe to do even without the lock.
About the code. Assuming the lock is implemented correctly then it is safe to do anything before release is called
I want an asynchronous thread to edit an object. Therefore I store a pointer to that object.
Data *pointer;
There is also a flag of type std::atomic<bool> to know if the secondary thread is modifying the object the pointer points to or not. While the flag holds true, the main thread won't affect the pointer and its underlying object.
std::atomic<bool> modifying;
void Thread()
{
// wait for jobs
for(;;)
{
// the flag is set to true my the main thread
// to let this thread start processing
if(modifying)
{
// modify the object the pointer points to,
// pass the pointer to a function to do so,
// and so on...
// the flag to false to tell the main thread
// that it can read the result from the pointer
// and prepare it for the next job
modifying = false;
}
}
}
How can I ensure thread safety?
I cannot wrap the pointer by std::atomic because from the secondary thread I need to pass the pointer to a function expecting a non atomic Data* type as parameter.
Do pointers even need to be declared as atomic specifically? I don't think that a processor would change threads during writing a single register. Or do I have to make it atomic anyway to prevent unwanted compiler optimizations?
If a pointer is atomic, is the underlying object so, too? In other words, could I modify the object using the pointer I get from pointer.load()?
Thanks for your clarification.
It sounds like what you want is to have the privilege to edit the object be mutually exclusive. This is exactly what mutexes were made for.
In general, suppose you have threads A and B, both of which want to update the same pointer. When, e.g., A wants to make an edit, it tries to lock() the mutex. If the mutex isn't already locked by B, this will succeed, and A can do its thing. If the mutex is already locked by B, then A will block (that is, stop executing) until B releases its lock on the mutex, at which point A will continue and do its thing as normal.
For a more concrete example of the syntax of C++11's mutexes, this page does a good job:
http://en.cppreference.com/w/cpp/thread/mutex
And, of course, I would recommend the pthreads library for an explanation of mutexes (and other threading concepts) in general:
https://computing.llnl.gov/tutorials/pthreads/#Mutexes
In your case, your code might look something like this:
std::mutex editing;
void Thread()
{
for(;;)
{
editing.lock();
// Do whatever editing you wanted to do here.
editing.unlock();
}
}
It's also worth noting the try_lock() function on the std::mutex class. This is very similar to lock(), except if the mutex is already locked then it will just return false to indicate that the lock couldn't be acquired, and continue. This would be useful if you want your thread to just forget about editing the object and continue if the other thread is already editing the object, instead of waiting for the other thread and then editing.
I have a basic sample which needs review (C++).
Let's say I have a function PublicFunc(), and another one called PrivateFunc(). I'd like to synchronize them carefully. But PrivateFunc can sometimes call PublicFunc as well what means we are calling it from the same thread. This causes blocks, and I'd like to solve it.
mutable boost::mutex m;
void PublicFunc() {
m.lock();
//Here it blocks, but why?
//What I need is to get the lock if this func was called from PrivateFunc(), so exactly from the same thread.
//But! It should definitely block on calling PublicFunc from outside while we are for example in the 'OtherPrivateFunc'.
//Do some stuff
//this is not necessary
m.unlock();
}
void PrivateFunc() {
m.lock();
PublicFunc();
OtherPrivateFunc();
m.unlock();
}
Which mutex or lock is the right one from the boost library?
Thank you!
A mutex may only be locked once; any call to lock the mutex while it is locked will block, even if the attempt to lock the mutex is made by the thread that holds the lock on the mutex.
If you want to be able to lock a mutex multiple times on the same thread, use recursive_mutex.
Alternatively, consider reorganizing your code so that you have one set of (private) member functions that assume the mutex is locked, and have all other functions delegate to these. This can make the code clearer and can make it easier to verify that the synchronization is correct.
I have am reviewing a colleague's Visual Studio 2008 C++03 application application and I've come across an implementation of a thread synchronization primitive (below).
Assuming SyncObject is implemented correctly, is the use of a boolean in the below code to know if the resource is locked or unlocked thread-safe? If no, can you walk through a "ThreadA" does this and "ThreadB" does that situation so I understand your logic?
class CMyLock
{
public:
CMyLock(SyncObject* object)
: object_(object), acquired_(false)
{
};
// return true if the resource is locked within the given timeout period
bool Lock(DWORD dwTimeOut = INFINITE)
{
acquired_ = object_->Lock(dwTimeOut);
return acquired_;
};
// return true if the resource is unlocked
bool Unlock()
{
if (acquired_)
acquired_ = !object_->Unlock();
return !acquired_;
};
// return true if the resource is locked
bool IsLocked() { return acquired_; };
private:
bool acquired_;
// some thread synchronization primitive
SyncObject* object_;
};
It is not threadsafe.
directly after m_pObject->Unlock() returns, another thread waiting on m_pObject->Lock(dwTimeOut) can return and set m_bAcquired to true, then the unlocking thread sets m_bAcquired to false and overwrites the locked state incorrectly (IsLocked will return false while the object is locked).
I see several serious problems with this code. In a code review, I would reject it.
It is not clear what this class is intended to be. It might be a thin proxy to a primitive. It might be an automatic locker. In either case, the design is wrong, and the documentation (none) does not elaborate.
It does not use RAII. This is a good idea no matter what this object is intended to be, but in the case of an automatic locker it is especially important.
It retains it's own state, which could be out of sync with other instances in the same thread. If, for example, you create 2 instances of this object on thread A, set one to locked and check the state of the other one, it should say locked but it won't.
Possibly most importantly, it is re-inventing the wheel at best.
Short answer: no
You need to lock for reading too, or you risk seeing a stale state.
no it's not - at least from what I can see. What may happen is that one thread calls lock and gets the lock and another thread accesses m_bAcquired before it's updated by the thread the causes the lock.
That's why you need a lock for reading as well asl Matthieu M. stated.
A: Lock
after m_pObject is locked but before m_bAcquired is set
B: IsLocked
--> returns false
A - still in Lock: m_pObject = true
so B has false information.
Other problem:
Unlock relies on m_bAcquired.
I think this object is meant to be used from within one single thread. So each thread has its own CSingleLock instance but they all use the same SyncObject. In this case, only SyncObject needs to be thread safe and it works.
Does anyone know how to check and see if a QMutex is locked, without using the function:
bool QMutex::tryLock()
The reason I don't want to use tryLock() is because it does two things:
Check and see if the mutex is locked.
If it's not locked then lock it.
For my purposes, I am not interested in performing this second step (locking the mutex).
I just want to know if it is locked or not.
Trying to lock a mutex is by definition the only way to tell if it's locked; otherwise when this imaginary function returned, how would you know if the mutex was still locked? It may have become unlocked while the function was returning; or more importantly, without performing all the cache-flushing and syncronization necessary to lock it, you couldn't actually be sure if it was locked or not.
OK, I'm guessing there is no real way to do what I'm asking without actually using tryLock().
This could be accomplished with the following code:
bool is_locked = true;
if( a_mutex.tryLock() )
{
a_mutex.unlock();
is_locked = false;
}
if( is_locked )
{
...
}
As you can see, it unlocks the QMutex, "a_mutex", if it was able to lock it.
Of course, this is not a perfect solution, as by the time it hits the 2nd if statement, the mutex's status could have changed.
Maybe a QSemaphore with one permit? The available() method may give you what you need.
QMutex is designed just for locking and unlocking functionality. Gathering statistics may be satisfied with some custom counters.
Try QSemaphore as #Luca Carion mentioned earlier.
static bool isLocked(const QBasicMutex *mut) {
auto mdata = reinterpret_cast<const QBasicAtomicPointer<QMutexData> *>(mut);
return mdata->load();
}
This code should work on Qt 5 and doesn't mess with the mutex state.
Every QBasicMutex holds a single (atomic) pointer (called d_ptr) that is NULL if not owned, a special value if it is owned but uncontested or a pointer to a platform dependent structure (on Unix, this is basically a pthread mutex) if the mutex is owned and contested.
We need the reinterpret_cast because d_ptr is private.
More info can be found here: https://woboq.com/blog/internals-of-qmutex-in-qt5.html
A legitimate use case is to verify that a mutex is indeed locked, for example if it is a function precondition. I suggest using Q_ASSERT(isLocked(...)) for this purpose.
Testing for an unlocked mutex is inherently unsafe and should not be done.