| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > многопоточность: Продавец-Продавец |
| Автор: cupper 14.2.2011, 15:41 | ||||
| есть классическая задача для многопоточности Продавец-покупатель. Она много где описывается, но обычно не где не описывается решение для агресивной политики доступа, т.е. когда пауз между продай - купи нету, и каждый наровит впихнуть/взять как можно больше. У меня же задача, чуть более сложней. Когда два разных потока пытаются получить доступ к одному и томуже ресурсу притом один (1) чисто на запись, второй (2) на чтение и запись. ведущий поток это (1), так как если не будет данных то (2) читать ничего не сможет. Это легко решается с помощью condition_variable. А вот как организовать возможность разделение доступа к ресурсу между (1) и (2) я не могу понять. Должны корректно выполнятся следующие ситуации: 1) если (1) постоянно пишет в ресурс, то как только (2) попробует чтото прочитаться из ресурса (и не сможет этого сделать) то последушию запросы (1) временно блокируются что бы (2) смог получить доступ к ресурсу 2) если (2) постоянно читает/пишет в ресурс, то как только (1) попробует чтото записать в ресурса (и не сможет этого сделать) то последушию запросы (2) временно блокируются что бы (1) смог получить доступ к ресурсу При этому (1) и (2) не должны покадить то место в котором они не смогли получить доступ, а должны доджаться когда они этот доступ получат. Это примерно выглядет так
Этот работает для случая когда есть искуственная пауза между вызовами push->push и pop->pop т.е. для случая
вероятность что pop() сможет влесть в работу потока1 крайне мала. |
| Автор: cupper 14.2.2011, 16:26 | ||
придумал такую штуку
При каждой попытке чтения (pop) мы пишем в буле переменную true свидетельствующую о том что нужно прочитать данные. Далее все как обычно пробуем залочить мютекс, и если не получается, то значит выполняется поток (1). В этом самом потоке (1) вызывается операция push в которой первый делом проверяется, а нге было ли попыток ЧИТАТЬ, и если была (значение ture у переменной) то мы для текущего потока отдаем остаток времение yield(). Единственно что меня смущает так это что я не совсем понимаю как работает yield() и всегда ли будет поведение которое я описал выше ? |
| Автор: cupper 15.2.2011, 10:21 | ||||||||
т.е. даже при таком раскладе
В потоке2 операция pop() особо долго не будет задерживаться из за того что в первом потоке постоянно занимается доступ ? Я видать попутал эту задачу с задачей писатель-много читателей, когда читатель действительно может не дождаться доступа к ресурсу из за того что к общей куче читателей постоянно могут прибавляться новые...
это вылезло из за
но вы правы, это излишне. |
| Автор: azesmcar 15.2.2011, 10:30 | ||||
cond.wait разблокирует мьютекс на время ожидания (пока не получит notification), в свою очередь push разблокирует его как только закончит свою работу. Т.е. на каждой итерации мьютекс освобождается, давая другому потоку возможность сделать свое дело. Любой, уважающий себя мьютекс должен дать поработать обоим потокам (смотри bounded waiting)
Там как раз пишущим потокам дается приоритет, так-как их мало. вот http://www.data-race.com/2011/02/01/readers-writers-%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B8/ я описывал. Добавлено @ 10:30 проверка тоже лишняя. |