Я пытался реализовать блокировку чтения / записи, используя только мьютекс (только для обучения). Когда я подумал, что покрыл все угловые случаи (поскольку программа работала с различными комбинациями), я понял, что проигнорировал тот факт (как он работал в Ubuntu), что мьютекс должен быть освобожден владельцем потока. Ниже моя реализация,
class rw_lock_t{
int NoOfReaders;
int NoOfWriters, NoOfWritersWaiting;
pthread_mutex_t class_mutex;
pthread_cond_t class_cond;
pthread_mutex_t data_mutex;
public:
rw_lock_t()
: NoOfReaders(0),
NoOfWriters(0), NoOfWritersWaiting(0)
{
pthread_mutex_init(&class_mutex, NULL);
pthread_mutex_init(&data_mutex, NULL);
pthread_cond_init(&class_cond, NULL);
}
void r_lock()
{
pthread_mutex_lock(&class_mutex);
//while(NoOfWriters!=0 || NoOfWritersWaiting!=0) //Writer Preference
while(NoOfWriters!=0)
{
pthread_cond_wait(&class_cond, &class_mutex);
}
if(NoOfReaders==0)
{
pthread_mutex_unlock(&class_mutex);
pthread_mutex_lock(&data_mutex);
pthread_mutex_lock(&class_mutex);
NoOfReaders++;
pthread_mutex_unlock(&class_mutex);
}
else if(NoOfReaders>0) //Already Locked
{
NoOfReaders++;
pthread_mutex_unlock(&class_mutex);
}
}
void w_lock()
{
pthread_mutex_lock(&class_mutex);
NoOfWritersWaiting++;
while(NoOfReaders!=0 && NoOfWriters!=0)
{
pthread_cond_wait(&class_cond, &class_mutex);
}
pthread_mutex_unlock(&class_mutex);
pthread_mutex_lock(&data_mutex);
pthread_mutex_lock(&class_mutex);
NoOfWritersWaiting--; NoOfWriters++;
pthread_mutex_unlock(&class_mutex);
}
void r_unlock()
{
pthread_mutex_lock(&class_mutex);
NoOfReaders--;
if(NoOfReaders==0)
pthread_mutex_unlock(&data_mutex);
pthread_mutex_unlock(&class_mutex);
pthread_cond_signal(&class_cond);
}
void w_unlock()
{
pthread_mutex_lock(&class_mutex);
NoOfWriters--;
if(NoOfWriters==0)
pthread_mutex_unlock(&data_mutex);
pthread_mutex_unlock(&class_mutex);
pthread_cond_signal(&class_cond);
}
};
Мой вопрос сейчас заключается в том, каков наилучший способ (минимальное изменение) исправить. Семафор определенно не используется, но я подумал о решениях ниже
Решение # 1
1) У меня будет специальный поток, просто для блокировки / разблокировки мьютекса для чтения.
2) Этот поток будет ожидать переменную условия для получения сигнала от r_lock или r_unlock.
3) r_lock и r_unlock вместо "pthread_mutex_lock / unlock (& data_mutex);" будут сигнализировать о блокировке выделенного потока.
4) Мне нужно запомнить много фактов для этой реализации,
Сигнализация и фактическая блокировка - это два разных события, поэтому может потребоваться синхронизация.
Потребуется мьютекс + condVariable + поток и дополнительная синхронизация.
Обновление: решение № 2
1) Поток, выполнивший фактическую блокировку, сохранит свою информацию глобально.
2) всякий раз, когда поток разблокируется, проверяется равенство проверки с глобальным значением.
3) Если совпадения будут ждать условия «NoOfReaders == 0» и разблокировать его.
Итак, есть ли лучший способ исправления программы.