Synchronous communication between 546-C + + threads (producer consumer model)

Two problems in multithreaded programming

1. Mutual exclusion between threads
Concurrency condition exists when multithreading runs = > code snippet in critical area = > guarantee its atomic operation = > Add mutex
Lightweight lock free CAS implementation

Execute strace. / a.out mutex command tracker in linux
=>The bottom layer is found to be pthread_mutex_t

2. Synchronous communication between threads
(if there is no communication between threads, each thread is scheduled by the CPU, and there is no execution order. Thread 1 and thread 2 are based on the CPU scheduling algorithm. Both threads may run first, which is uncertain. The operation order between threads is uncertain, so the multithreaded program has problems and is difficult to reproduce, because no one knows the execution order of threads at that time , we can generally get the thread stack information of each thread to analyze whether there is deadlock. We need to ensure the running order between threads)
Communication is: thread 1 and thread 2 run together. What thread 2 wants to do must first rely on thread 1 to complete some things, and then tell thread 2 that this part is done, and thread 2 can continue to execute downward. Or thread 1 needs to do some operations next. These operations require thread 2 to finish other things, and then notify thread 1 that it has finished, and then thread 1 can do these operations)
Producer, consumer, thread model

Producer consumer thread model

The producer produces an article and informs the consumer to consume an article; When the consumer has finished consuming, the consumer will inform the producer to continue producing goods

#include <iostream>
#Include < thread > / / multithreaded header file 
#Include < mutex > / / header file of mutex 
#include <condition_ Variable > / / header file of condition variable 
#Include < queue > / / all C + + stl containers are not thread safe
using namespace std;

std::mutex mtx;//Define a mutex to perform mutex operations between threads
std::condition_variable cv;//Define condition variables for synchronous communication between threads

//The producer produces an article and informs the consumer to consume one; After consumption, the consumer will inform the producer to continue to produce goods
class Queue
{
public:
	void put(int val)//Production goods
	{
		unique_lock<std::mutex> lck(mtx);//unique_ptr
		while (!que.empty())
		{
			//If que is not empty, the producer should inform the consumer to consume. After the consumer has consumed, the producer can continue to produce
			//The producer thread enters #1 waiting state and #2 releases the mtx mutex
			cv.wait(lck);//The current thread is suspended, waiting, and the current lock Lck. Lock () Lck. Unlock is released
		}
		que.push(val);
		/* 
		notify_one:Notification to wake up another thread 
		notify_all:Notification to wake up all other threads
		Inform all other threads that I have produced an item. Please consume it quickly
		When other threads get this notification, they will go from waiting state = > to blocking state = >, but they can continue to execute downward only after obtaining the mutex
		*/
		cv.notify_all(); 
		cout << "Producer production:" << val << "Item No" << endl;
	}
	int get()//Consumer goods
	{
		//lock_ guard<std::mutex> guard(mtx);// Equivalent to scoped_ptr
		unique_lock<std::mutex> lck(mtx);//Equivalent to unique_ptr is safer 
		while (que.empty())
		{
			//The consumer thread finds that que is empty and notifies the producer that Mr. thread produces the item
			//#1 suspend and enter the waiting state #2 to release mutex
			cv.wait(lck);
		}//If other threads execute notify, the current thread will change from waiting state = > to blocking state = > but it can continue to execute downward only after obtaining the mutex 
		int val = que.front();
		que.pop();
		cv.notify_all();//Inform other threads that I'm finished consuming. Let's hurry to produce
		cout << "Consumer consumption:" << val << "Item No" << endl;
		return val;
	}
private:
	queue<int> que;
};

void producer(Queue *que)//Producer thread
{
	for (int i = 1; i <= 10; ++i)
	{
		que->put(i);
		std::this_thread::sleep_for(std::chrono::milliseconds(100));//Sleep for 100 milliseconds 
	}
}
void consumer(Queue *que)//Consumer thread
{
	for (int i = 1; i <= 10; ++i)
	{
		que->get();
		std::this_thread::sleep_for(std::chrono::milliseconds(100));//Sleep for 100 milliseconds 
	}
}
int main()
{
	Queue que;//Queue shared by two threads

	std::thread t1(producer, &que);//Open producer thread 
	std::thread t2(consumer, &que);//Open consumer thread 

	t1.join();
	t2.join();

	return 0;
}

Tags: C++ Multithreading

Posted on Sat, 11 Sep 2021 15:43:56 -0400 by waffle72