C ++ Concurrency and multithreading study notes - scheduling between threads

  • condition_variable
  • wait()
  • notify_one
  • notify_all

condition_variable

The actual use condition variables:

For example there are two threads A and B, a waiting condition is satisfied thread A, (there are messages in the message queue to be processed), thread B dedicated to lose the data queue. When placed into the thread B data while the notification thread B A, started down. Design server in the background, there is a thread blocking read message, and parse it, placed in the queue, then thread B also informed A, get request from the queue and processed.

 

a) socket in the art that the application server can be the same as opening a file to read the data.

b) the thread B reads the data and puts it into the message queue.

c) Thread B Thread wake A, A thread to get data from the queue.

d) completion of server processes the request and returns the result.

By a condition variable class may be such that A waits B:

:( review the original code by double locked so that every judge is empty, then made if the lock is empty)

 

the ProcessRequest {class 
public: 
	// added to the command queue a 
	void inMsgRecvQueue () { 
		
		for (int I = 0; I <100000; I ++) { 
			// :: lock_guard STD <STD :: the mutex> sbguard (my_mutex) ; 
			COUT << "insert element" << endl; 
			m_msgRecvQueue.push_back (I); // assumed command queue represented player 

		} // occupation time slice 
	} 

	BOOL outMsgLULProc (int & command) { 
		// by double locking, avoiding every program comes in both locked. 
		(! m_msgRecvQueue.empty ()) IF 
		{ 
			STD :: lock_guard <STD :: the mutex> sbguard (my_mutex); 

			IF (! m_msgRecvQueue.empty ()) { 
				int = m_msgRecvQueue.front Command (); 
				m_msgRecvQueue.pop_front (); 
				to true return; 
			} 
			return to false; 
	}
		outMsgRecvQueue void () { 
			int Command = 0; 
			for (int I = 0; I <100000; I ++) { 
				
				BOOL outMsgLULProc Result = (Command); 
				IF (Result == to true) { 
					COUT << "outMsgRecvQueue () execution remove an element "<< endl; 
				} 
				the else 
				{ 
					COUT <<" outMsgRecvQueue () is also performed, but the message queue is empty "<< endl; 
					// message queue is empty 
				} 
				
				// occupation time slice 
			} 
		} 
	
Private: 
	STD: : list <int> m_msgRecvQueue; // vessel for representing commands sent from the player 
	STD :: my_mutex the mutex; 
};

  Use class std :: condition_variable to replace the double lock, to wait for a fulfillment of the conditions, this class needs and mutex with the work, with the time required to generate the object class.

pirvate:
    std::condition_variable my_condition;

  

wait()

A queue modification: wait is stuck in here, you need to modify the queue thread.

	outMsgRecvQueue void () { 
		int Command = 0; 
		the while (to true) { 
			STD unique_lock is :: <STD :: the mutex> sbguard1 (my_mutex); 
			my_condition.wait (sbguard1, [the this] { 
				! IF (m_msgRecvQueue.empty ()) / / lambda expression is a call object (function) 
					return to true; 
				the else 
					return to false; 
			}); // wait for a thing the wait 
		// the wait (para1, Para2) 
		// para1: mutex 
		// para2: first Lambda expressions two parameters return value is False 
		// so will unlock the mutex, and blocked the line until another thread calls notify_one () 
		// If there is no second argument, then just as the second parameter returns False the same effect 
		} 
	}

  Of course, after a wait () can be solved early unique_lock (), and execution logic.

 

notify_one

The original blocked process awakened. After the wait began restoration work, and recovery

a) wait () constantly tries to acquire the mutex lock, try to get the lock. If you can not get a lock, the process stuck in wait here, if acquired, wait went down.

b) to actually get a lock on equal locked it. If the wait second parameter (lambda), it is determined lambda expressions,

     If the expression is false, in turn unlock the mutex. And then another thread to sleep.

     If the expression is true, the wait return process go down (mutex is locked at this time).

     If the second parameter does not wait, wait returns the

	inMsgRecvQueue void () { 
		
		for (int I = 0; I <100; I ++) { 
			STD :: lock_guard <STD :: the mutex> sbguard (my_mutex); 
			m_msgRecvQueue.push_back (I); // assumed that the queue represented players command 
			cout << "insert element" << endl; 
			my_condition.notify_one (); 
		} // occupation time slice 
	}

 

At the same time the possibility of obtaining locks:

1) void inMsgRecvQueue()

2) void outMsgRecvQueue()

At the same time the possibility of a lock of competition may arise, that is to say if you run into outMsgRecvQueue () logic of the statement is executed when the queue into at least one element, then it is not the case in and out of order execution may occur.

 out in the implementation of logical statements of the delay, if in this case wake, out the card is not in the state of wait (), then this time notify_one () call has no effect.

 

think deeply

Write code in commerce, must be understood.

In the thread entry point, there may be multiple data queue, but this time to deal with how to do? Open more thread processing? Or current limiting, over 200 unprocessed data, it stuck?

notify_all

Guess you like

Origin www.cnblogs.com/rynerlute/p/11839268.html