LINUX.ORG.RU

C++: Есть ли в boost такая сущность?

 , ,


0

3

Когда-то писал такой класс, но где-то посеял. Могу снова наваять, но может уже такое в бусте есть?

Есть 4 потока и 500 млн. сущностей. Хочется подпускать к каждой из них не более 1 потока, но не запрещать одновременный доступ 4 потоков к разным сущностям. Создать 500 млн мьютексов - это лишнее, ибо потока всего 4.

Я делал класс, который держал 4 мьютекса и выдавал их «в аренду» потокам по предъявлению ID сущности, к которой поток хочет получить доступ. На один и тот же идентификатор выдавался один и тот же мьютекс, на разные идентификаторы - разные мьютексы. После использования, поток сдавал мьютекс обратно в гардероб и мьютекс мог быть переиспользован для доступа к другому ID.

Хотя изобретать велосипеды и круто, но может такое уже есть где-нибудь в бусте?

★☆

Последнее исправление: kiverattes (всего исправлений: 1)

Простейший рецепт: 1 мьютекс который охраняет массив на 4 элемента, содержащего id, 1 условная переменная которая сигналит об освобождении любого id. Нужно захватить id - захватил мьютекс, проверил нет ли в массиве id: есть - ждем в цикле условной переменной, повторяем проверку; нет - закидываем id в массив, освобождаем мьютекс, сигналим условной переменной.

nerdogeek
()
#pragma once

#include <pthread.h>

template <typename T>
class Semaphore
{
	private:
		pthread_mutex_t mutex;
		pthread_cond_t cv;
		T res;
	public:
		Semaphore(T t) :res(t) {
			pthread_mutex_init(&mutex, NULL);
			pthread_cond_init(&cv, NULL);
		}
		~Semaphore() {
			pthread_mutex_destroy(&mutex);
			pthread_cond_destroy(&cv);
		}
		inline void add(T r=T(1)) {
			pthread_mutex_lock(&mutex);
			res += r;
			pthread_cond_broadcast(&cv);
			pthread_mutex_unlock(&mutex);
		}
		inline void dec(T r=T(1)) {
			pthread_mutex_lock(&mutex);
			while (true) {
				if (res >= r) {
					res -= r;
					pthread_mutex_unlock(&mutex);
					return;
				} else {
					pthread_cond_wait(&cv, &mutex);
				}
			}
			pthread_mutex_unlock(&mutex);
		}
};

Иницируешь Semaphore <unsigned> sem(4), и раздаёшь потокам. При доступе к сущности делаешь dec(), после делаешь add().

nanoolinux ★★★★
()
Ответ на: комментарий от nanoolinux

Это никак не поможет запретить нескольким потокам обращаться к одному элементу списка одновременно.

invy ★★★★★
()

Вы мне свои решения-то не пишите, я и сам умный. Вопрос в том, что взять готовое.

kiverattes ★☆
() автор топика
Ответ на: комментарий от invy

Да, согласен. Правильное замечание.

Для случая, когда все сущности обрабатываются последовательно, можно сделать атомарный доступ к списку этих самых сущностей. Использование семафора в придачу позволит реализовать то, что задумал тс.

nanoolinux ★★★★
()

Зачем тебе вообще эта «аренда мутексов»? Сделай коллекцию из занятых id, защити ее одним мутексом. Далее когда берешь тредом очередной id захватывай мутекс и смотри, нет ли этого id в коллекции. Если нет, кладешь его в коллекцию и освобождаешь мутекс. Если есть, значит не судьба. Когда закончишь работу удаляешь id из коллекции.

Absurd ★★★
()
Последнее исправление: Absurd (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.