@ShowmanRS

Как вывести динамический массив внутри синхронизированного потока?

Решите классическую проблему «поставщик – потребитель» с использованием описанных в лабораторной работе средств синхронизации.
Один поток производит данные, другой поток их потребляет. В промежуток времени между изготовлением и потреблением данные хранятся в буфере.
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <thread> 
#include <mutex>

using namespace std;
 
pthread_mutex_t mtx;
pthread_cond_t cnd;

void addv(int &endb,int &nacb,int& buf) 
{
	pthread_mutex_lock(&mtx);
	while (1) 
	{
	
	    if ((endb == 10 && nacb == 0)||(endb == nacb-1))
	   {
		pthread_cond_wait(&cnd,&mtx);
	   }
	   else 
	   {
			buf[&endb] = endb;
			cout << "Simbol " << buf[&endb] << " in" << endl;		
			endb++;
			if (endb == 10)
			{
				endb = 0;
			}
			pthread_cond_signal(&cnd);
			pthread_mutex_unlock(&mtx);
		}
	usleep(50000);
	}
}
 
void delv(int &endb,int &nacb,int& buf) 
{	
	pthread_mutex_lock(&mtx);
	while (1) 
	{
		if (endb == nacb)
		{
		pthread_cond_wait(&cnd,&mtx);
		}
		else 
		{     
			cout << "Simbol " << buf[&nacb] << " out" << endl;
			buf[&nacb] = 0;
			nacb++;
			if (nacb == 10)
			{
				nacb=0;
			}
		pthread_cond_signal(&cnd);
		pthread_mutex_unlock(&mtx);			
		}
	usleep(50000);
	}
}
int main() 
{	
	int buf[10];
	int nacb = 0;
	int endb = 0;
	thread thr1(addv,ref(endb),ref(nacb),ref(*buf));
	thread thr2(delv,ref(endb),ref(nacb),ref(*buf));
	thr1.join();
	thr2.join();
	return 0;
}

2 функция почему то отказывается работать и постоянно выводит "1" и после чего перестаёт отдавать мьютекс, хз что делать.
  • Вопрос задан
  • 78 просмотров
Решения вопроса 1
@res2001
Developer, ex-admin
В addv и delv в блоке else вы разблокируете мьютекс и дальше он у вас все время в разблокированном состоянии.
Так что никакой синхронизации не происходит в принципе.
Вам не нужно разблокировать мьютекс, просто вместо usleep используйте pthread_cond_timedwait. Внутри этой функции мьютекс неявно разблокируется, потом ждет наступление события (сигнал или таймаут), затем мьютекс снова захватывается и только после этого возвращается управление вызывающему коду.
Аналогично работает и pthread_cond_wait, только без таймаута.
В этом случае блок if следует переписать так что бы не было двойного вызова pthread_cond_wait.

Не увидел в коде где вы инициализируете мьютекс и условную переменную, а так же где вы их удаляете. Без инициализации все функции их использующие будет возвращать ошибки.

Нужно ВСЕГДА обрабатывать возвращаемые значения системных функций!

Почему вы потоки используете из std, а мьютекс и условную переменную из pthread? Где логика?
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы