![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| cupper |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 525 Регистрация: 29.11.2006 Репутация: 1 Всего: 1 |
есть классическая задача для многопоточности Продавец-покупатель. Она много где описывается, но обычно не где не описывается решение для агресивной политики доступа, т.е. когда пауз между продай - купи нету, и каждый наровит впихнуть/взять как можно больше.
У меня же задача, чуть более сложней. Когда два разных потока пытаются получить доступ к одному и томуже ресурсу притом один (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 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 525 Регистрация: 29.11.2006 Репутация: 1 Всего: 1 |
придумал такую штуку
При каждой попытке чтения (pop) мы пишем в буле переменную true свидетельствующую о том что нужно прочитать данные. Далее все как обычно пробуем залочить мютекс, и если не получается, то значит выполняется поток (1). В этом самом потоке (1) вызывается операция push в которой первый делом проверяется, а нге было ли попыток ЧИТАТЬ, и если была (значение ture у переменной) то мы для текущего потока отдаем остаток времение yield(). Единственно что меня смущает так это что я не совсем понимаю как работает yield() и всегда ли будет поведение которое я описал выше ? |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
С чего это ей быть крайне малой? Назови причину, по которой у потока, вызывающего push вдруг появился приоритет. Они одинаково блокируют тут же mutex, почему именно у pop нет шансов? После push()-а первый поток освобождает мьютекс, тем самым давая возможность второму потоку вызвать pop().
это зачем еще? Это сообщение отредактировал(а) azesmcar - 15.2.2011, 08:35 |
|||
|
||||
| cupper |
|
||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 525 Регистрация: 29.11.2006 Репутация: 1 Всего: 1 |
т.е. даже при таком раскладе
В потоке2 операция pop() особо долго не будет задерживаться из за того что в первом потоке постоянно занимается доступ ? Я видать попутал эту задачу с задачей писатель-много читателей, когда читатель действительно может не дождаться доступа к ресурсу из за того что к общей куче читателей постоянно могут прибавляться новые...
это вылезло из за
но вы правы, это излишне. |
||||||||
|
|||||||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
cond.wait разблокирует мьютекс на время ожидания (пока не получит notification), в свою очередь push разблокирует его как только закончит свою работу. Т.е. на каждой итерации мьютекс освобождается, давая другому потоку возможность сделать свое дело. Любой, уважающий себя мьютекс должен дать поработать обоим потокам (смотри bounded waiting) Там как раз пишущим потокам дается приоритет, так-как их мало. вот тут я описывал. Добавлено @ 10:30 проверка тоже лишняя. Это сообщение отредактировал(а) azesmcar - 15.2.2011, 11:01 |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |