What happens if I call wait on a notified condition variable

Suppose I have two thread state variables and one C ++ 11 common variable. What happens if thread1 calls a notification and after that call thread2 to wait? will thread2 block forever or will it continue to work due to a notification call on thread1?

Edit:

enum bcLockOperation { bcLockOperation_Light = -1, bcLockOperation_Medium = 50, bcLockOperation_Heavy = 1 } class BC_COREDLL_EXP bcCustomMutex { private: bcCustomMutex(const bcCustomMutex&); bcCustomMutex& operator=(const bcCustomMutex&); protected: bcAtomic<int> mFlag; bcMutex mMutex; bcConditionVariable mCond; public: bcCustomMutex() { bcAtomicOperation::bcAtomicInit(mFlag, 0); }; ~bcCustomMutex() {}; /*bcMutex(const bcMutex& pOther) = delete; bcMutex& operator=(const bcMutex& pOther) = delete;*/ bcInline void lock(bcLockOperation pLockOperation = bcLockOperation_Medium) { bcINT32 lNewLoopCount = static_cast<bcINT32>(pLockOperation); bcINT32 lLoopCounter = 0; bcINT32 lExpected = 0; bcINT32 lLoopCount = bcAtomicOperation::bcAtomicLoad(mFlag, bcMemoryOrder_Relaxed); while (true) { while(bcAtomicOperation::bcAtomicLoad(mFlag, bcMemoryOrder_Relaxed) != 0 && lLoopCounter != lLoopCount) ++lLoopCounter; bcAtomicOperation::bcAtomicCompareExchangeStrong( mFlag, &lExpected, lNewLoopCount, bcMemoryOrder_Acquire, bcMemoryOrder_Relaxed); if(lExpected == 0) { //mMutex.lock(); return; } else if(lLoopCounter == lLoopCount) { bcLockGuard<bcMutex> lGuard(mMutex); mCond.wait(mMutex); } else continue; } }; bcInline void UnLock() { bcAtomicOperation::bcAtomicStore(mFlag, 0, bcMemoryOrder_Relaxed); bcUniqueLock<bcMutex> lGuard(mMutex); mCond.notifyOne(); }; bcInline bcBOOL TryLock() { }; }; 

I want to write my own mutex so that each thread can provide an argument representing the complexity of the operations that the current thread wants to perform. If the complexity of the operation is low, other threads will be in a loop, such as spin lock, but if the complexity of the operation is medium, each thread will iterate 50 times and then sleep on the condition variable, and if the operation is very complex, other threads will go straight ahead .

Now suppose thread1 blocks this mutex, and thread2 goes on hold because its loopCounter reaches its end and to the right before locking the mutex state variable, thread1 requests notify the condition variable. Now thread2 will sleep until another thread locks the user mutex and then unlocks it.

I am new to multithreading and I want to learn. I know that my class may contain errors or it may be completely wrong, but is there a way to fix this problem or a good algorithm for writing such a mutex.

Another question: is the ordering of atoms correctly ordered?

+6
source share
2 answers

Thread2 will block until someone triggers a notification. Calls to notify release threads waiting during a call. If there are no threads waiting, they do nothing. They are not saved.

+13
source

Typically, both the code that decides to wait and the code that decides to notify use the same mutex. Therefore, thread2 will never skip the notification from thread1.

Here's a classic example of a block-based parallel queue:

 void push(int x) { lock_guard<mutex> guard{queue_mutex}; thequeue.push(x); not_empty_condition.notify_one(); } int pop() { unique_lock<mutex> guard{queue_mutex}; not_empty_condition.wait(guard, []{ return !thequeue.empty(); } ); int x = thequeue.front(); thequeue.pop(); return x; } 

Suppose thread1 and thread2 work push() and pop() respectively. Only one of them will be in the critical section at a time.

  • If thread2 has a lock, either it never waits because the queue is not empty (therefore, the β€œlose” notification is harmless), or it sits there waiting for the notification (which will not be lost).

  • If thread1 gets a lock, it will put the element in the queue; if thread2 waited, it will receive a notification appropriately; if thread2 was still waiting for the mutex, it will never wait, because there is at least one element in the queue, so the loss of notifications is harmless.

Thus, the notification is lost if it is not required in the first place.

Now, if you have another use of state variables, when a β€œlose” notification has any effect, I believe that you either have a race condition or the wrong tool is used at all.

+10
source

Source: https://habr.com/ru/post/955120/


All Articles