C++ multi-threaded consumer producer model

1. Mutex lock and condition variable implementation, no limit on buffer size

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <queue>

using namespace std;

queue<int> tq;

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *consumer(void *arg)
{
	
	while(true)
	{
		pthread_mutex_lock(&mutex);
		
		while(tq.empty())//用while防止虚假唤醒
		{
			pthread_cond_wait(&cond,&mutex);//当缓冲区为空就等待信号
		}

	        int m=tq.front();
                tq.pop();

		pthread_mutex_unlock(&mutex);
		
		printf("%ld th thread get-%d- message!\n",(long)arg,m);//输出语句放外边,因为锁的粒度越小越好
		usleep(1000);
	}	
}

void *producer(void *arg)//multiple productors
{
	while(true)
	{
		pthread_mutex_lock(&mutex);
		tq.push((int)(long)arg);
		pthread_mutex_unlock(&mutex);
		pthread_cond_broadcast(&cond);//生产数据就广播数据
		usleep(15000);
	}       
}

void producer2()//single productor
{
	int i=0;
	while(true)
	{
		pthread_mutex_lock(&mutex);
		tq.push(i++);
		pthread_mutex_unlock(&mutex);
		pthread_cond_broadcast(&cond);
		usleep(10000);
	}
}

int main()
{
	pthread_t c1,c2,c3;
	pthread_t p1,p2;

	pthread_create(&c1,NULL,consumer,(void *)1);
	pthread_create(&c2,NULL,consumer,(void *)2);
	pthread_create(&c3,NULL,consumer,(void *)3);
	pthread_create(&p1,NULL,producer,(void *)1);
	pthread_create(&p2,NULL,producer,(void *)2);

        //producter2();
	pthread_join(c1,NULL);
	pthread_join(c2,NULL);
	pthread_join(c3,NULL);
	pthread_join(p1,NULL);
	pthread_join(p2,NULL);

	return 0;
}

operation result

PS: Use while conditional judgment instead of if to prevent false wake-up

False wake-up means that the operating system may have an internal problem and mistakenly wakes up the condition variable. Second, the producer sends a signal to the condition variables that all threads are waiting for when broadcasting, but one thread has not finished executing the awakened atom before other threads. The data is consumed during the operation, and the buffer is empty as a result, causing another thread to be awakened to perform the data fetching operation and get lonely. So the while loop can determine

2. Implemented using semaphores (PV operations) and mutex locks, the buffer size can be limited

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <queue>
#include <semaphore.h>

using namespace std;

int msgid=1;

struct message
{
	int id;
	int pid;
};

queue<message> q;

sem_t Empty,Full;
pthread_mutex_t mutex;

void *consumer(void *arg)
{
	int c_id=(int)(long)arg;
	while(true)
	{
		sem_wait(&Full);//P操作 Full--
		pthread_mutex_lock(&mutex);
		message tmp=q.front();
		q.pop();
		pthread_mutex_unlock(&mutex);
		sem_post(&Empty);//V操作 Empty++
		
		printf("-%d-th consumer get id-%d- pid-%d- message\n",c_id,tmp.id,tmp.pid);
		
		sleep(2);
	}
}

void *producer(void *arg)
{
	int p_id=(int)(long)arg;
	while(true)
	{
		sem_wait(&Empty);//P操作 Empty--
		pthread_mutex_lock(&mutex);//上锁的顺序不能互换
		q.push({msgid++,p_id});
		pthread_mutex_unlock(&mutex);
		sem_post(&Full);//V操作 Full++
		
		sleep(1);
	}
}

void *monitor(void *arg)//观察线程
{
	while(true)
	{
		printf("--size of q is -%d-\n",(int)q.size());
		sleep(1);
	}
}

int main()
{
	pthread_t c1,c2,c3;
	pthread_t p1,p2,p3;
	pthread_t m1;
	
	sem_init(&Empty,0,5);//队列限制大小为5
	sem_init(&Full,0,0);
	
	pthread_create(&m1,NULL,monitor,NULL);
	
	pthread_create(&c1,NULL,consumer,(void *)1);
	pthread_create(&c2,NULL,consumer,(void *)2);
	pthread_create(&c3,NULL,consumer,(void *)3);
	
	pthread_create(&p1,NULL,producer,(void *)1);
	pthread_create(&p2,NULL,producer,(void *)2);
	pthread_create(&p3,NULL,producer,(void *)3);
	
	pthread_join(m1,NULL);
	
	pthread_join(c1,NULL);
	pthread_join(c2,NULL);
	pthread_join(c3,NULL);
	
	pthread_join(p1,NULL);
	pthread_join(p2,NULL);
	pthread_join(p3,NULL);
	
	return 0;
}


 Running results (you can see that the maximum buffer size is 5)

Accumulating steps will lead you to a thousand miles.

Let’s start learning multi-threaded programming from consumer and producer issues!

Guess you like

Origin blog.csdn.net/qq_30798083/article/details/130774781