Страниц: 1 [2] 3
  Печать  
Автор Тема: multi producer single consumer  (Прочитано 16075 раз)
ob1
Hero Member
*****
Offline Offline

Сообщений: 629


What has two thumbs up and doesn't give a crap?


Просмотр профиля WWW
« Ответ #15 : Марта 01, 2011, 08:47:27 am »

Не мешайте Деревенко пыжиться. У него такое огромное самомнение, которое он так забавно везде выставляет... Интересно, он всё-всё за деньги делает? И можно даже посмотреть... И втроём... И недорого, кстати... Как такие люди называются? ;-}
Записан
oder
Гость
« Ответ #16 : Марта 01, 2011, 12:15:32 pm »

Не мешайте Деревенко пыжиться. У него такое огромное самомнение, которое он так забавно везде выставляет... Интересно, он всё-всё за деньги делает? И можно даже посмотреть... И втроём... И недорого, кстати... Как такие люди называются? ;-}
Да ладно, ob1 (пардон, имени-фамилии не нашёл), ты тоже - не сахар. Каждый развлекается в меру своих возможностей и своей распущенности. Smiley
За деньги не всё. Но, только, я уже давно не юнный мальчик и на собственной шкуре убедился, что доказывать кому-нибудь что-нибудь - дело неблагодарное. Не веришь на слово, хочешь чтоб тебя убеждали - это уже услуга: плати деньги или катись подальше. Я должен сделать рабочие примеры так и эдак, запустить их как минимум на нескольких машинах, собрать результаты сравнить их и запостить здесь, чтоб какой-то неизвестный мне vshemm в чём-то убедился. Зачем мне это? Я лучше что-нибудь полезное сделаю.
Записан
vshemm
Sr. Member
****
Offline Offline

Сообщений: 317


Просмотр профиля
« Ответ #17 : Марта 01, 2011, 10:03:23 pm »

Логика - просто улет Smiley Мне ничего объяснять не нужно, это, скорре, нужно Вам. Потому что среди технически
подкованных людей, да и просто логически мыслящих принято аргументировать свою позицию. Ну а вы "опустили"
на словах сановский/оракловский код, и, когда вам намекнули про аргументы, врубили заднюю, мол, я просто так ничего
делать не буду и т.п. (при этом начав потихоньку отказываться от своих утверждений). Про "написание и отладку"
кода вообще смех, ибо тут 2 варианта: это все уже проделано и остается только запостить результаты, либо
ваши предложения по оптимизации действительно голословны. Хотя, имхо, тут этап кодирования и отладки вообще лишний.

Впрочем, давайте развлекаться дальше. Предлагаю следующие условия спора. Меняем в сорцах

Код:
pthread_cond_signal(&b->more);
pthread_mutex_unlock(&b->mutex);
местами, как и
Код:
pthread_cond_signal(&b->less);
pthread_mutex_unlock(&b->mutex);
тоже.

Далее я показываю, что в общем случае 1) будут идти ассерты, ставка 1024 рубля или 2) привожу несколько причин
неработоспособности кода, ставка 2048 рублей Wink
Записан
oder
Гость
« Ответ #18 : Марта 01, 2011, 10:39:04 pm »

Про "написание и отладку" кода вообще смех, ибо тут 2 варианта: это все уже проделано и остается только запостить результаты, либо ваши предложения по оптимизации действительно голословны.
Ничего не проделано - всё по-честному.

Впрочем, давайте развлекаться дальше. Предлагаю следующие условия спора. Меняем в сорцах
Код:
pthread_cond_signal(&b->more);
pthread_mutex_unlock(&b->mutex);
местами, как и
Код:
pthread_cond_signal(&b->less);
pthread_mutex_unlock(&b->mutex);
тоже.

Далее я показываю, что в общем случае 1) будут идти ассерты, ставка 1024 рубля или 2) привожу несколько причин
неработоспособности кода, ставка 2048 рублей Wink

Относительно 1) - согласен.
Нужны три добровольца с навыками программирования рассудить спор (навыки работы с многопоточностью необязательны). Есть желающие?

Относительно 2) - впринципе, именно в такой  постановке - тоже согласен. Только здесь намного сложнее с суддейством. Нужны люди достаточно глубоко понимающие синхронизацию, чтоб осмыслить и оценить правильность того, что будете рассказывать вы и того, что буду рассказывать я. Не уверен, есть ли на форуме такие (точнее, целых трое Smiley). Есть кто покруче, кто согласился бы?
Записан
vshemm
Sr. Member
****
Offline Offline

Сообщений: 317


Просмотр профиля
« Ответ #19 : Марта 01, 2011, 11:25:02 pm »

Ок. Вы должны понимать, что 2) более общий, чем 1) и может его включать в себя, поэтому выберите один из вариантов.
P.S. Оплата через Yandex деньги, ибо я не буду заморачиваться с другими способами ради таких сумм (это мой ответный акт вежливости - даю возможность Вам соскочить).
Записан
oder
Гость
« Ответ #20 : Марта 02, 2011, 01:18:20 am »

Ок. Вы должны понимать, что 2) более общий, чем 1) и может его включать в себя, поэтому выберите один из вариантов.
P.S. Оплата через Yandex деньги, ибо я не буду заморачиваться с другими способами ради таких сумм (это мой ответный акт вежливости - даю возможность Вам соскочить).

Нет, 2 -не более общий.
Assert - чисто отладочная вещь и, по-нормальному, в релизной сборке должна быть отключена. Поэтому, если падают только ассерты, но при их отключении всё работает нормально, то это значит, что "всё работает нормально". Тоесть, это значит, что неправильным является само условие ассерта и ничего более.
Поэтому я согласен на оба варианта сразу, если во втором варианте вы ещё что-нибудь, кроме ассертов, сможете предложить.
Относительно Yandex-денег - тоже не имею никаких возражений, если расскажете, где в Украине можно их обналичить и/или оплатить (оплатить, думаю, можно и из платёжной карты - с этим, обычно, проблем не бывает, а вот обналичивать не все платёжные системы спешат с радостью). Как опция, пополните мне деньгами мобильный: я укажу сайт и номер телефона.
Записан
vshemm
Sr. Member
****
Offline Offline

Сообщений: 317


Просмотр профиля
« Ответ #21 : Марта 02, 2011, 02:10:24 am »

Ок, ставка итого 3072 рубля. Проблема с оплатой решается легко - проигравший оплачивает накладные расходы на перевод удобный победителю. Мне удобнее на яндекс деньги Wink
Завтра с утра ждите пост.
Записан
Hed
Jr. Member
**
Offline Offline

Сообщений: 98


Просмотр профиля
« Ответ #22 : Марта 02, 2011, 11:16:49 am »

Assert - чисто отладочная вещь и, по-нормальному, в релизной сборке должна быть отключена.

По посиксу assert всегда отключается в сборке без ключа -g
Записан
oder
Гость
« Ответ #23 : Марта 02, 2011, 12:09:19 pm »

Assert - чисто отладочная вещь и, по-нормальному, в релизной сборке должна быть отключена.

По посиксу assert всегда отключается в сборке без ключа -g

Неправильно. Assert отключается при определенном символе NDEBUG (#define NDEBUG или -DNDEBUG в командной строке). Ключ -g определяет только наличие/отсутствие отладочных символов в бинарном файле, но никак не влияет на сам код, который генерируется.
« Последнее редактирование: Марта 02, 2011, 12:54:34 pm от oder » Записан
Hed
Jr. Member
**
Offline Offline

Сообщений: 98


Просмотр профиля
« Ответ #24 : Марта 02, 2011, 02:46:26 pm »

Assert - чисто отладочная вещь и, по-нормальному, в релизной сборке должна быть отключена.

По посиксу assert всегда отключается в сборке без ключа -g

Неправильно. Assert отключается при определенном символе NDEBUG (#define NDEBUG или -DNDEBUG в командной строке). Ключ -g определяет только наличие/отсутствие отладочных символов в бинарном файле, но никак не влияет на сам код, который генерируется.

и то верно  Wink ну что же, будем знать
Записан
vshemm
Sr. Member
****
Offline Offline

Сообщений: 317


Просмотр профиля
« Ответ #25 : Марта 02, 2011, 10:21:48 pm »

Ну, начнем.

Проблема смены порядка сигнала и отпускания мьютекса заключается в появлении момента, когда другая нить сможет доступиться к уже измененной защищаемой переменной (в нашем случае это b->occupied), но не успеть встать на ожидание кондвара. В этом случае сигнал может потеряться, и, как следствие, произойдет дедлок. Данная ситуация хорошо изучена и много где описана, например, по той же ссылке, что и обсуждаемый код http://download.oracle.com/docs/cd/E19455-01/806-5257/6je9h032r/index.html. Цитирую:

Цитировать
The Lost Wake-Up Problem

Calling pthread_cond_signal() or pthread_cond_broadcast() when the thread does not hold the mutex lock associated with the condition can lead to lost wake-up bugs.

A lost wake-up occurs when:

* A thread calls pthread_cond_signal() or pthread_cond_broadcast().
* And another thread is between the test of the condition and the call to pthread_cond_wait().
* And no threads are waiting.

The signal has no effect, and therefore is lost.

Если этого недостаточно, могу привести execution-path данного события (построчно).
Записан
oder
Гость
« Ответ #26 : Марта 03, 2011, 01:09:32 am »

Проблема смены порядка сигнала и отпускания мьютекса заключается в появлении момента, когда другая нить сможет доступиться к уже измененной защищаемой переменной (в нашем случае это b->occupied), но не успеть встать на ожидание кондвара. В этом случае сигнал может потеряться, и, как следствие, произойдет дедлок.
Цитировать
A lost wake-up occurs when:
* A thread calls pthread_cond_signal() or pthread_cond_broadcast().
* And another thread is between the test of the condition and the call to pthread_cond_wait().
* And no threads are waiting.

К сожалению (вашему) дедлока не произойдёт потому, что посмотрите, при каких условиях нить (например, производитель) идёт на ожидание кондвара. Она идёт туда, когда она проверила, что буфер полон и нет ни одного свободного места, чтоб положить свои новые данные. Если бы она даже сигнал и поймала, она всё-равно, вернулась бы на проверку условия цикла, опять убедилась, что свободных мест нет и опять ушла бы ждать. Так что, потеря сигнала в данном случае, наборот, является благом, так как предотвращает лишнее безцельное пробуждение/засыпание потока.
Когда производитель уснёт и освободит мютекс, тогда уже следующий потребитель сможет войти и освободить одно место в буфере. И после выхода из критической секции он своим сигналом уже гарантированно пробудит ожидающий поток-производитель, который его гарантированно будет ждать и для которого уже гарантированно будет место, чтоб он мог положить свои данные и со спокойной совестью уйти прочь.
Ход моих мыслей вам понятен?
Записан
oder
Гость
« Ответ #27 : Марта 03, 2011, 01:50:20 am »

Хотите ещё узнать, почему assert() никогда не упадёт? Даже теоретически...
Потому, что цикл while работает таким образом, что сначала вычисляется выражение в условии цикла, если оно "истина" производится выполнение тела цикла и потом опять производится вычисление выражения в усливии цикла. Выход из цикла while произойдёт только тогда, когда его условие вычислится как "ложь". А условие ассерта, который непосредственно следует после цикла является противоположным к условию цикла и оно автоматически приобретёт значение "истина". Вычисление обоих последовательных условий производится с захваченным мютексом (либо потому, что в тело цикла нить вообще не входила и мютекс не отпускала, либо потому, что она вышла с захваченным мютексом из pthread_cond_wait и пошла на проверку условия и выход из цикла с тем же захваченным мютексом). Таким образом, количество занятых элементов в буфере между вычислениями данных последовательных условий никоим образом поменяться не может, а, следовательно, и сами условия всегда будут возвращать противоположный результат. И ассерт не упадёт не зависимо от того, сигналится ли кондвар в критической секции, за пределами критической секции или не сигналится вообще. Он вообще, впринципе, никогда не упадёт. Нормальный оптимизирующий компилятор (коим является и gcc), вообще, условие ассерта вычислять не будет, а просто проигнорирует его, как выражение, которое всегда должно возвращать "истину", потому, что это, фактически, - двойное вычисление того же самого выражения без каких-либо вызовов функций или модификаций памяти в промежутке.
Записан
vshemm
Sr. Member
****
Offline Offline

Сообщений: 317


Просмотр профиля
« Ответ #28 : Марта 03, 2011, 03:22:33 am »

Ну вот куда вы так спешите? Ваш ход мыслей мне понятен даже больше, чем вы думаете. Только вот чтобы не было бардака и прочих оказий, разбираться нужно постепенно, шаг за шагом. Поэтому пока мы не закроем вопрос с The Lost Wake-Up Problem дальше никуда двигаться не будем.
Вы описываете некоторые рабочие случаи, которые ничего не доказывают, в то время как у меня задача привести, как минимум, один нерабочий, что и будет доказательством.

Поэтому повторяю еще раз, в оракловском документе ясно указано, что сигналить не под захваченным мьютексом нельзя. Это также отмечено во многих других источниках. Данный факт полностью проигнорирован. Мое беглое описание данной проблемы также осталось без комментариев. Остается только привести execution path, ибо проще я объяснить не смогу, но если и это не поможет, то я оставляю за собой право тоже действовать нелогично.
Записан
oder
Гость
« Ответ #29 : Марта 03, 2011, 10:44:07 am »

Конечно, приводите execution path. Это всё расставит на свои места.
Относительно статьи Оракла - да, конечно существуют случаи, когда pthread_cond_signal за критическую секцию выносить нельзя. И их, возможно, даже и большинство. Но в данном конкретном случае выносить можно. Здесь система "имеет память" в виде счётчика занятых/свободных мест в буфере. И этот счётчик (под мютексом!) позволяет безболезненно терять сигналы.
Записан
Страниц: 1 [2] 3
  Печать  
 
Перейти в: