Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[52.91.54.203] |
|
Страницы: (6) 1 [2] 3 4 ... Последняя » все ( Перейти к последнему сообщению ) |
Сообщ.
#16
,
|
|
|
offsop was censored Да нет, я желаю на каждый "профессиональный взгляд" иметь кроме бла-бла-бла - что-то подтверждающее. Ну напиши мне строку в моем коде, обоснуй ошибку. Так уже третья моя просьба мимо. Спрашивается, а нахрена твои слова, если по существу не можешь указать где плохо и как лучше? Извини за эмоции. Бинго! Вот этого ДЖВА года ждал! А еще надежнее - записывать параллельно в бумажный журнал. Цитата Wound @ Сегодня у тебя один продьюсер и один потребитель. Завтра может быть несколько потребителей, а после завтра - появятся несколько продьюсеров и несколько потребителей. А ты почитай-почитай про lock-free структуры. Когда прочитаешь, прочитай еще раз. И только потом ты поймешь, что то, что я процитировал тебя выше - лютая дичь от незнания. Я читаю и учусь, и ты читай. |
Сообщ.
#17
,
|
|
|
Этот аргумент я себе запишу в смартфон!!! Это не должно умереть! |
Сообщ.
#18
,
|
|
|
offtop was censored Цитата JoeUser @ Да нет, я желаю на каждый "профессиональный взгляд" иметь кроме бла-бла-бла - что-то подтверждающее. Ну напиши мне строку в моем коде, обоснуй ошибку. Так уже третья моя просьба мимо. Спрашивается, а нахрена твои слова, если по существу не можешь указать где плохо и как лучше? Извини за эмоции. Я тебе уже привел хренову тучу аргументов - отказаться от std::thread, тебе этого мало? Так а нахрена ты тут тему вообще создал? Комить уже, ёпта. Все там нормалёк, остальные косяки по мере поступления разрулишь. Цитата JoeUser @ Бинго! Вот этого ДЖВА года ждал! А еще надежнее - записывать параллельно в бумажный журнал. Конечно надежнее, когда у тебя есть общий ресурс! Потому что все понятно что и где у тебя происходит. Вот тут есть лок - значит ресурс защищен, а вот тут нет лока - значит возможно косяк. В случае с lock-free алгоритмами - косяк тебя может поджидать на каждом шагу, потому что у тебя нет блокировок и гарантировать что эта операция потокобезопасная - нельзя, вернее можно, если углубленно знать всякие ньюансы использования lock-free(но это явно не про тебя). Допустим ты сам не можешь гарантировать что твой код потокобезопасен и не содержит костылей. Банальное переписывание его с блокировками - можно уже гарантировать что код не содержит каких то подводных камней, и что вот в таких то местах - он гарантированно потокобезопасен. Цитата JoeUser @ А ты почитай-почитай про lock-free структуры. Когда прочитаешь, прочитай еще раз. И только потом ты поймешь, что то, что я процитировал тебя выше - лютая дичь от незнания. Я читаю и учусь, и ты читай. Ну конечно. Ты даже постом выше уже признал что std::cout у тебя не потокобезопасен. Цитата JoeUser @ Этот аргумент я себе запишу в смартфон!!! Это не должно умереть! Конечно запиши, и желательно еще сделай обои на рабочий стол с этим текстом, чтоб не забыть. offtop was censored |
Сообщ.
#19
,
|
|
|
Цитата JoeUser @ Этот аргумент я себе запишу в смартфон!!! Это не должно умереть! А так оно и есть. С блокировками у тебя всегда есть части кода, гарантированно выполняющиеся одним потоком. Это банально проще отлаживать и куда быстрее писать, чем сидеть и представлять "а вот тут у меня будет переключение контекста, сюда вклинится другой поток и выполнит воон ту фигню" с lock-free. Так что да, решение с блокировками наверняка окажется надёжнее из-за своей простоты. |
Сообщ.
#20
,
|
|
|
offtop was censored
Цитата Wound @ Я тебе уже привел хренову тучу аргументов - отказаться от std::thread, тебе этого мало? Прости, я что-то кроме бла-бла-бла не заметил сути. Перечисли, пожалуйста (ПОЖАЛУЙСТА)!!! еще раз по пунктам. Чем тебе плох std::thread? Цитата Wound @ потому что у тебя нет блокировок и гарантировать что эта операция потокобезопасная - нельзя Т.е как я тебя понимаю, если в Стандарте написано, что данная операция из текущей версии STL атомарная - тебе насрать?! Ты этому не доверяешь? Цитата Wound @ Ты даже постом выше уже признал что std::cout у тебя не потокобезопасен. Не "даже" а "всего лишь" - ощути разницу! А ты из говно-момента делаешь себе корону. Хотя нет, мелочей нет. Ты тут прав. Это есть косяк и он должен быть запомнен на будущее. Цитата Wound @ как Pavia, за то что не привел тебе пруфы А вот на зло тебе и ему не выдам! Он не просто ограничился "тезисом", а пытался обосновать. А ты, как всегда, с шашкой на-голо в бой. Нихрена не понял, но по ходу разберемся Киля, не парься - ты на форуме есть, и это клёво! Даже если мы стреляемся из разных барикад |
Сообщ.
#21
,
|
|
|
Цитата OpenGL @ А так оно и есть. С блокировками у тебя всегда есть части кода, гарантированно выполняющиеся одним потоком. Это банально проще отлаживать и куда быстрее писать, чем сидеть и представлять "а вот тут у меня будет переключение контекста, сюда вклинится другой поток и выполнит воон ту фигню" с lock-free. Так что да, решение с блокировками наверняка окажется надёжнее из-за своей простоты. А мне не надо "надежнее надежного". Мне надо чтобы инварианты из STL выполнялись. И если там есть часть функций/методов которые работают с lock-free структурами, я буду ими пользоваться. Нравится вам это или нет. Я вас спросил в первом посте - есть ошибки? А вы меня грузите опасениями!!! Мне этого не надо, я это не просил !!! |
Сообщ.
#22
,
|
|
|
Тут интересное по теме - Параллельное программирование на С++ в действии.Уильямс
В том числе и по lock-free структурам. |
Сообщ.
#23
,
|
|
|
Цитата JoeUser @ Мне надо чтобы инварианты из STL выполнялись. Какие инварианты и как их нарушает решение с блокировкой? Цитата JoeUser @ Я вас спросил в первом посте - есть ошибки? Так я и не спорю. Хочешь делать нерационально - дело твоё, мне-то что? |
Сообщ.
#24
,
|
|
|
Цитата OpenGL @ Какие инварианты и как их нарушает решение с блокировкой? "Перпендикулярный" вопрос ващето! Я про атомарные операции библиотеки... Они и гарантируют инварианты. "Решения с блокировкой" - это вами навязываемая шляпа, к которой я в данном треде никакого отношения не имею. Цитата OpenGL @ Хочешь делать нерационально - дело твоё, мне-то что? Вот пошла тема!!! Рациональность. Прекрасненько. Тут есть о чем поговорить. Расскажи мне, пожалуйста, как сделать рациональнее! Вводная: есть GUI процесс, есть процесс, опрашивающий Кардридер в неблокирующем режиме. В моем синтетическом примере основной процесс = ReaderThread, а процесс опроса Кардридера WriteThread. Жду более "оптимальный" вариант и конечно же его обоснование! |
Сообщ.
#25
,
|
|
|
Цитата JoeUser @ Я про атомарные операции библиотеки... Они и гарантируют инварианты. Тогда ты просто сам не понял, что сказал, потому что в этом контексте фраза "чтобы инварианты из STL выполнялись." теряет смысл. Цитата JoeUser @ Вводная: есть GUI процесс, есть процесс, опрашивающий Кардридер в неблокирующем режиме. У тебя там lock-free контейнеры при межпроцессном взаимодействии? Мсье знает толк, однако. Чем тупое решение с блокировкой не устроило-то? Добавлено По-моему тут что-то из разряда "если в руках молоток, то всё кажется гвоздями" |
Сообщ.
#26
,
|
|
|
Цитата OpenGL @ Тогда ты просто сам не понял, что сказал, потому что в этом контексте фраза "чтобы инварианты из STL выполнялись." теряет смысл. Не понял тебя. Атомарные операции гарантируют "единоличный" доступ/операции. Считывание, обмен... Ты о каком смысле вообще? Цитата OpenGL @ Мсье знает толк, однако. Чем тупое решение с блокировкой не устроило-то? Мусье, а вы бы мне могли обосновать необходимость блокировки, где и без нее можно обойтись? И еще, мусье, вы немножко знакомы с тезисом Уильяма из Оккамы ("Бритва Оккамы"), и если "да", спросите себя - нахрена городить огород? Я имею ввиду- блокировками, если и без них все прекрасно? |
Сообщ.
#27
,
|
|
|
Цитата JoeUser @ Не понял тебя. Атомарные операции гарантируют "единоличный" доступ/операции. Считывание, обмен... Ты о каком смысле вообще? Ну перечитай ещё раз Разжёвывать очевидную мысль, да ещё оффтопя, мне не интересно. Цитата JoeUser @ Мусье, а вы бы мне могли обосновать необходимость блокировки, где и без нее можно обойтись? Звучит примерно как "обоснуй необходимость компилятора, ведь можно в hex кодах всё написать". Можно, конечно, просто это сложно. lock free алгоритмы в разы более сложные в написании и отладке, да ещё и далеко не всегда они работают быстрее (по-моему очередь и стек так вообще часто медленней оказываются, чем с блокировкой), так что в данном случае всё наоборот - ты должен обосновать необходимость реализовывать с lock-free. У тебя есть замеры времени в реальных условиях, из которых следует, что ты много времени тратишь на на ожидания в мьютексах? Или может быть твоя основная цель это научиться работать с lock-free? Если ответа на оба вопроса "нет", то твоё решение менее рационально, чем решение с блокировками. |
Сообщ.
#28
,
|
|
|
Цитата OpenGL @ Разжёвывать очевидную мысль, да ещё оффтопя, мне не интересно. Я немного гиперболизирую, несколько в обход вежливому общению. Просто представь, ты пишешь утверждение типа: censored. M Вы с OpenGL не поняли друг друга. Это не повод обижаться и раскультуриваться. Я понял каждого, хоть и не с первого раза. Вы оба правы, но говорите о разных предметных областях. Цитата OpenGL @ Звучит примерно как "обоснуй необходимость компилятора, ведь можно в hex кодах всё написать". Что мой FreeStack так серьезно сложен? Да ладно? Да ладно! Есть другое мнение. Для компиляции Хэллоу Ворлда не нужно ставить lcc (в 624KB), а нужно ставить вcю студию в более чем 11GB. Зачем? ДА НА ВСЯКИЙ СЛУЧАЙ !!! Прекрасная логика! ПРЕСНАЯ ВОДА ПО ПРЕЖНЕМУ detected! В первой теме код и вопросы. Это тема. |
Сообщ.
#29
,
|
|
|
Цитата JoeUser @ Вводная: есть GUI процесс, есть процесс, опрашивающий Кардридер в неблокирующем режиме. В моем синтетическом примере основной процесс = ReaderThread, а процесс опроса Кардридера WriteThread. Жду более "оптимальный" вариант и конечно же его обоснование! Не хотелось бы встревать в жёсткую дискуссию..что-то я устал за последнее время. Могу просто рассказать, как делал сам. А в качестве обоснования могу привести наисерьёзнейший аргумент: "Нутром чую, что правильно - именно так". Скрытый текст Итак, есть GUI - приложение с его оконной процедурой. Есть рабочий поток (или потоки) которые что-то там много делают. Пусть будет карт-ридер, это неважно. Хоть 10. 1. Смастерим класс-коммуникационный объект, для работы и обмена между разными потоками. Это будет шаблонный класс. Его основа - две потоко-безопасные очереди. Разного направления, условно "туда и обратно". Где хочешь их бери, хоть сам луди. (а что такое очередь? Это массив, индексы которого рассчитываются по алгоритму очереди) 2. Напишем класс-интерфейс для возбуждения событий. Назовём его, например, I_RiseEvent. У него будет роутина RiseEvent, которая будет реализовываться в дочерних классах. 3. Класс нашего главного окна (или любого другого, которого надо) назначим наследником - того библиотечного класса окна и интерфейса I_RiseEvent. Множественным наследованием. 4. Тоже самое с нашим рабочим потоком - он наследник базового класса - потока и I_RiseEvent. 5. Инициализация комм-объекта произойдёт после создания объекта рабочего потока и окна. Дело в том, что объекту коммуникации надо обязательно передать указатели на объекты-интерфейсы потока и окна. Идея тут простая - когда один из участников обмена засылает структуру обмена в очередь, автоматически возбуждается событие на принимающей стороне. А поскольку интерфейс - абстрактен, и реализация возбуждения события происходит в конкретном объекте конкретного класса проекта, значит наш коммуникационный объект от проекта вообще не зависит. Это прекрасно, и мы можем включить такой класс в библиотеку и пользоваться проверенным решением во всех проектах. Поскольку наш коммуникационный объект (и используемые им очереди) мы сделаем шаблонным классом. А значит, пригодным для работы с любыми типами данных. 6. как всё работает - допустим юзер щёлкнул по кнопке - обработчик кнопки заполнил структуру с запросом, занёс её в коммуникационный объект в направлении "туда". Сам факт занесения вызвал процедуру "RiseEvent" у объекта-потока. Эта процедура подожгла семафор. Семафор разбудил поток, который мирно спал на Wait-процедуре. Поток запустил обработчик работы/опроса чего надо. Допустим, карт-ридера. Через некоторое время (а главному окну всё это пофигу) операция завершилась. Как-то. Обработчик потока записал результаты в какую-то там (заранее изобретённую) структуру и заслал в коммуникационный объект в очередь "обратно". Сам факт записи в очередь вызвал процедуру "RisEvent" уже главного окна. Чтобы не работать в контексте рабочего потока, окно пошлёт само себе асинхронное, заранее предусмотренное сообщение. Получив сообщение, обработчик окна этого сообщения извлечёт из очереди структуру с результатом... и у юзера в строке статуса (например) появится сообщение - "Операция такая-то завершилась успешно" В одном приложении может быть сколько надо потоков и сколько угодно таких связей между ними. При этом один поток может получать разные запросы от разных коммуникационных объектов и выполнять последовательно разную работу разными обработчиками. Ограничение одно - любой поток в среднем должен справляться с поставленными задачами, чтобы очереди запросов не стали неконтролируемо расти. Можно также организовать последовательный конвейер между многими потоками, каждый из которых производит свою часть работы по преобразованию данных. Привожу пример - получаем по сети данные и строим график. 1-й рабочий поток непосредственно работает с сетью, получает данные, проверяет, преобразовывает, засылает в комм-объект, засыпает. 2-й рабочий поток-графопостроитель. Получает данные 1-го, просыпается, начинает рисовать, результат засылает в комм-объект (другой уже) засыпает. 3-й поток - главного окна. Возбуждение события приведёт к извлечению картинки и перерисовке ею главного окна. Однако, графопостроитель - приёмник запросов не от одного комм-обекта. Он должен получать данные от главного окна : - при измерении размеров окна - при изменении графических параметров - цветА, фонты, вид гафика, их количество итд. Все, что можно назвать "формой представления". И поток-графопостроитель действительно будет выполнять все эти запросы от 3-х источников последовательно и слать результат одному приёмнику (в виде картинки главному потоку). При этом работа отдельных частей приложения максимально абстрагирована от других частей приложения. Структура приложения становится полностью асинхронной, никто-никого-никогда не ждёт. Свою работу сделал, сунул результат в очередь и всё. Дальнейшая судьба данных не волнует. Конвейер. Есть конечно и сложности реализации. Если такой проект будет плохо документирован, то разбираться потом в многочисленных перекрёстных связях между объектами будет не сразу быстро. Кроме того, потребуется специально сделанная процедура корректной де-активации многочисленных связей - иначе умирающие потоки не дадут нормально завершиться приложению. Как-то так. |
Сообщ.
#30
,
|
|
|
Цитата JoeUser @ Что мой FreeStack так серьезно сложен? Да ладно? Да ладно! Да. Он не сложнее быстрой сортировки, например, но если кто-то будет писать сортировку просто так вместо использования той, что в стандартной библиотеке, мотивируя это тем, что она несложная, то это кто-то просто решает задачу нерационально. Как и ты сейчас. |