LINUX.ORG.RU

[Threads] Реализация неблокирующего чтения на мьютексах


0

1

Суть такова. Есть два класса объектов - читатели и писатели. Необходимо осуществить их совместный доступ к разделяемому ресурсу по следующей схеме: читатели могут одновременно читать ресурс до тех пор, пока не появился хотя бы один писатель. При появлении писателя все вновь прибывающие читатели разбегаются в ужасе блокируются до тех пор, пока писатель не закончит работу. Если на момент появления писателя уже происходило чтение несколькими читателями, то сам писатель блокируется до тех пор, пока последний незаблокированный читатель не закончит читать. Писать одновременно имеет право только один писатель (логично). Важное условие: синхронизацию необходимо осущетвить с помощью мьютексов.

Решение на Си, в котором (где-то) определен тип mutex и функции void lock(mutex *), void unlock(mutex *):



static mutex WR;  /* где-нибудь инициализируется заранее */
static mutex R;   /* аналогично */

static int locked = 0;
static int countR = 0;

void Read(void){
  /* читатели */
  int flag = 0;
  lock(R);
  countR++;
  if(!locked){ lock(RW); flag=1; }
  unlock(R);
   
  /* ... некое чтение ресурса ... */

  lock(R);
  countR--;
  if(flag){ locked = 0; unlock(RW); }
  unlock(R);
}



void Write(void){
  /* писатели */
  int weHaveReaders;
  do{
    lock(R);
    if(countR > 0) weHaveReaders = 1;
    else { 
       locked = 0;
       unlock(R); 
       lock(RW); 
       weHaveReaders = 0; 
    }
  }while(weHaveReaders);


  /* ... некая запись того же ресурса ... */

  lock(R);
  unlock(RW);
  locked = 0;
  unlock(R);
}

Вопросы: корректно ли решение? Как бы вы решили эту задачу?

Спасибо за внимание.



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

Ответ на: комментарий от ktulhu666

Да, нужны именно мьютексы, поскольку это наиболее примитивное, а значит распростарнённое средство синхронизации.

gandjubas
() автор топика
Ответ на: комментарий от gandjubas

это с чего ты взял? не знаю, как в си++, но в других языках, мьютекс обычно является обёрткой к вызову саспенда всех нитей (или части нитей, если это поддерживается языком). Это можно делать и вручную.

В плане мьютексов: http://linuxportal.ru/forums/index.php/t/24008/ http://www.life-prog.ru/view_zam2.php?id=64 !!!!!!!!!!!!! Многопоточность Linux. Mutex'ы http://www.cyberguru.ru/programming/cpp/multithreading-intro-page3.html

Если Вы не хотите иметь половых отношений со своей программой (при условии, что её выполнение в 1,01-2 раза медленнее не критично), используйте другой язык. Яву уже давным-давно можно компилить под конкретную архитектуру. Для питона же есть куча оптимизаторов и даже комплятор (на самом деле транслятор в си++, но это не важно), но он не будет работать с гуёвыми и другими приложениями, использующими не стандартные либы питоны). Хотя Вам, думаю, подойдет. Пример на питоне: http://habrahabr.ru/blogs/python/39744/

Ну а если уж Вы - ярый адепт сношений с си++, то рекомендую посмотреть это: http://habrahabr.ru/blogs/cpp/111514/ Или погуглить на тему дополнительных либ, которые решают проблему одновременного доступа.

ktulhu666 ☆☆☆
()
Ответ на: комментарий от gandjubas

если Вы на чистом си кодите, то я могу пожелать Вам только творческих упехов и удовлетворения от актов кодинга под си :) (и не бойтесь искать уже готовые либы и юзать их. это может ускорить разработку в несколько раз).

ktulhu666 ☆☆☆
()
Ответ на: комментарий от ktulhu666

> если Вы на чистом си кодите

Я программирую на ява, С#, C, потихоньку изучаю питон. Это так, к слову.

gandjubas
() автор топика
Ответ на: комментарий от ktulhu666

> Ну а если уж Вы - ярый адепт сношений с си++

Я ярый адепт принципа: не повторяйся. Это значит, в частности, что если серверный код использует некий алгоритм, который необходимо также использовать на клиенте, при этом серверный код написан на С, то необходимо взять этот серверный код, скомпилировать под нужную платформу и поставить с клиентским приложением. Поддерживать два исходника, да ещё на двух разных языках не имею ни малейшего желания.

gandjubas
() автор топика
Ответ на: комментарий от gandjubas

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

ktulhu666 ☆☆☆
()
Ответ на: комментарий от ktulhu666

А с чего ты взял, что несколько языков сразу подходят для моей задачи? Задача, кстати, уже решена меньшими силами - с помощью одного мьютекса и массива указателей. Как верно заметил товарищ Vamp, надо тщательнее разрабатывать структуры данных.

gandjubas
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.