Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 15.09.19 12:25
Оценка:
Несмотря на большой опыт, довелось использовать только mutex и event; да еще разок скопипастил код с conditional variable. А хочется войти в тему поглубже — как в принципе грамотно организовать многопоточное приложение. Но если гуглить, везде в основном описывают разные примитивы синхронизации и что надо захватывать ресурсы в одном порядке, а это я и так знаю. Более интересны паттерны дизайна на эту тему, а также тонкие моменты.

Например, я как-то сделал класс для многопоточного счетчика через операцию ++. А тимлид сказал что так нельзя, ибо стандартная сигнатура операции ++ не позволяет корректно вернуть результат в многопоточной среде, и надо использовать функцию-член типа inc(). Вот таких нюансов хотелось бы (не в смысле С++, а в смысле принципов работы с переменными).

Конкретно, стоит задача написать сервер для небольшой сессионной MMO-игры. Я интуитивно понимаю, что клиентов надо обрабатывать в разных потоках, чтобы использовать все ядра проца. И притом желательно через тред-пул, поскольку клиент=поток будет слишком накладно если много клиентов. Но выразить это в грамотную архитектуру не могу (могу наколбасить связку из мутексов и возможно будет работать), но хочется ясного понимания как это спроектировать.

Что посоветуете прочитать?


P.S. Языком, скорее всего, будет не(!) С++, поэтому желательно без привязки к языку.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Отредактировано 17.09.2019 12:58 Basil2 . Предыдущая версия .
Re: Что почитать про многопоточность?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 15.09.19 12:58
Оценка: 19 (3)
Здравствуйте, Basil2, Вы писали:

B>Несмотря на большой опыт, довелось использовать только mutex и event; да еще разок скопипастил код с conditional variable. А хочется войти в тему поглубже — как в принципе грамотно организовать многопоточное приложение. Но если гуглить, везде в основном описывают разные примитивы синхронизации и что надо захватывать ресурсы в одном порядке, а это я и так знаю. Более интересны паттерны дизайна на эту тему, а также тонкие моменты.


Я бы сказал что паттерна, основных, на данный момент два три: CSP, акторы и прямой путь в ад — шареная память. Самопальная реализация скорее зло, на которое можно идти если ты очень хорошо понимаешь что делаешь, тут, судя по вопросу, не тот случай. Хорошей реализации CSP для C++ не знаю, а про акторов может so5team подсказать, они тут часто свой SObjectizer рекламируют
Автор: so5team
Дата: 24.05.19
.

B>Конкретно, стоит задача написать сервер для небольшой сессионной MMO-игры. Я интуитивно понимаю, что клиентов надо обрабатывать в разных потоках, чтобы использовать все ядра проца. И притом желательно через тред-пул, поскольку клиент=поток будет слишком накладно если много клиентов. Но выразить это в грамотную архитектуру не могу (могу наколбасить связку из мутексов и возможно будет работать), но хочется ясного понимания как это спроектировать.


Я правильно понимаю, что планируется писать на C++? Если да, то можно начать с азов, C++ Concurrency in Action
Автор: kaa.python
Дата: 05.01.19
, как раз недавно свежачок подвезли. Эту книгу стоит прочитать вне зависимости от того, будете пользоваться фрэймворком или будете велосипедить.

B>Что посоветуете прочитать?


Ну и вообще, я бы порекомендовал подумать про инструмент в первую очередь и, если здравый смысл возобладает, не брать C++ для этой задачи, он тут не нужен ну вот вообще совсем. Я, как обычно, советую Go — быстро и просто с приличной скоростью. Если здравый смысл не победит и вы будете писать на C++, то вот прям ну крайне важно начать с фреймфорка, который будет решать вам задачи связанные с многопоточтностью, велосипед будет дорогой и мучительный.
Отредактировано 15.09.2019 13:37 kaa.python . Предыдущая версия . Еще …
Отредактировано 15.09.2019 13:32 kaa.python . Предыдущая версия .
Re: Что почитать про многопоточность?
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 16.09.19 07:55
Оценка:
Здравствуйте, Basil2, Вы писали:

B>Несмотря на большой опыт, довелось использовать только mutex и event; да еще разок скопипастил код с conditional variable. А хочется войти в тему поглубже — как в принципе грамотно организовать многопоточное приложение. Но если гуглить, везде в основном описывают разные примитивы синхронизации и что надо захватывать ресурсы в одном порядке, а это я и так знаю. Более интересны паттерны дизайна на эту тему, а также тонкие моменты.

Есть хорошая книга "Параллельное и распределённое программирование на С++", там рассказывают немного о том как вообще можно организовать многопоточность с отсылкой к сетям Петри для моделирования. Советую ознакомится.

B>Например, я как-то сделал класс для многопоточного счетчика через операцию ++. А тимлид сказал что так нельзя, ибо стандартная сигнатура операции ++ не позволяет корректно вернуть результат в многопоточной среде, и надо использовать функцию-член типа inc(). Вот таких нюансов хотелось бы (не в смысле С++, а в смысле принципов работы с переменными).


B>Конкретно, стоит задача написать сервер для небольшой сессионной MMO-игры. Я интуитивно понимаю, что клиентов надо обрабатывать в разных потоках, чтобы использовать все ядра проца. И притом желательно через тред-пул, поскольку клиент=поток будет слишком накладно если много клиентов. Но выразить это в грамотную архитектуру не могу (могу наколбасить связку из мутексов и возможно будет работать), но хочется ясного понимания как это спроектировать.

Я так понимаю что при воздействии игрока на мир он должен пересчитываться. Мне кажется надо обрабатывать не клиента, а запросы, а клиент это тупо некоторая модель данных.
Sic luceat lux!
Re: Что почитать про многопоточность?
От: Sharov Россия  
Дата: 16.09.19 09:34
Оценка: 13 (2)
Здравствуйте, Basil2, Вы писали:

B>Несмотря на большой опыт, довелось использовать только mutex и event; да еще разок скопипастил код с conditional variable. А хочется войти в тему поглубже — как в принципе грамотно организовать многопоточное приложение. Но если гуглить, везде в основном описывают разные примитивы синхронизации и что надо захватывать ресурсы в одном порядке, а это я и так знаю. Более интересны паттерны дизайна на эту тему, а также тонкие моменты.


B>Например, я как-то сделал класс для многопоточного счетчика через операцию ++. А тимлид сказал что так нельзя, ибо стандартная сигнатура операции ++ не позволяет корректно вернуть результат в многопоточной среде, и надо использовать функцию-член типа inc(). Вот таких нюансов хотелось бы (не в смысле С++, а в смысле принципов работы с переменными).


B>Конкретно, стоит задача написать сервер для небольшой сессионной MMO-игры. Я интуитивно понимаю, что клиентов надо обрабатывать в разных потоках, чтобы использовать все ядра проца. И притом желательно через тред-пул, поскольку клиент=поток будет слишком накладно если много клиентов. Но выразить это в грамотную архитектуру не могу (могу наколбасить связку из мутексов и возможно будет работать), но хочется ясного понимания как это спроектировать.


B>Что посоветуете прочитать?


Наверное не совсем то, но мне ента книга помогла въехать в тему -- https://www.amazon.com/Synchronization-Algorithms-Concurrent-Programming-Taubenfeld/dp/0131972596
Еще вот на енту взгляните -- https://www.ozon.ru/context/detail/id/137764980/
Кодом людям нужно помогать!
Re[2]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 16.09.19 12:31
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Есть хорошая книга "Параллельное и распределённое программирование на С++", там рассказывают немного о том как вообще можно организовать многопоточность с отсылкой к сетям Петри для моделирования. Советую ознакомится.


Спасибо, присмотрюсь. Только язык видимо будет уже не С++.

K>Я так понимаю что при воздействии игрока на мир он должен пересчитываться. Мне кажется надо обрабатывать не клиента, а запросы, а клиент это тупо некоторая модель данных.


Да; я просто считал что "клиент = запрос(ы)". Тут правда в предыдущем посте подкинули идею с акторами и это действительно идея. Не лочить игровой мир при модификации, а просто отправлять все изменения "хозяину мира", а он сам их проставит безо всяких лочек.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[2]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 16.09.19 12:56
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>Я правильно понимаю, что планируется писать на C++? Если да, то можно начать с азов,


Нет, будет скорее всего Rust.

KP>Я бы сказал что паттерна, основных, на данный момент два три: CSP, акторы и прямой путь в ад — шареная память. Самопальная реализация скорее зло, на которое можно идти если ты очень хорошо понимаешь что делаешь, тут, судя по вопросу, не тот случай.


Изначально я думал рискнуть и попробовать шареную память — заодно и узнать, так ли хороша защита для многопоточности в Rust. CSP я загуглил но не понял, а вот идея с акторами мне понравилась. Типа есть "хозяин мира", то есть карты на которой идет игра, и есть обработчики событий от игроков. И обработчики событий не пытаются сами лезть в карту под лочкой, а шлют хозяину запросы. А хозяин все делает вообще без лочек, т.к. он единственный владелец карты. По идее, в Rust тоже есть каналы (как и в Go), так что может получиться относительно нативно, без особых фреймворков.

Но это не отменяет общей архитектуры. Ведь так получаются целых три слоя потоков: сетевые с соединением (плюс главный на котором сделан listen), обработчики запросов от клиентов, владельцы карт (игровых сессий). И все это как-то надо разруливать...
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re: Что почитать про многопоточность?
От: Pzz Россия https://github.com/alexpevzner
Дата: 16.09.19 13:01
Оценка:
Здравствуйте, Basil2, Вы писали:

B>Например, я как-то сделал класс для многопоточного счетчика через операцию ++. А тимлид сказал что так нельзя, ибо стандартная сигнатура операции ++ не позволяет корректно вернуть результат в многопоточной среде, и надо использовать функцию-член типа inc(). Вот таких нюансов хотелось бы (не в смысле С++, а в смысле принципов работы с переменными).


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

B>Конкретно, стоит задача написать сервер для небольшой сессионной MMO-игры. Я интуитивно понимаю, что клиентов надо обрабатывать в разных потоках, чтобы использовать все ядра проца. И притом желательно через тред-пул, поскольку клиент=поток будет слишком накладно если много клиентов. Но выразить это в грамотную архитектуру не могу (могу наколбасить связку из мутексов и возможно будет работать), но хочется ясного понимания как это спроектировать.


Если хочется выжать из железа 100%, это, как раз, не слишком светлая идея, выделять по потоку на клиента. Ну а если 100% из железа выжимать не обязательно, зато хочется простого и понятного кода, я бы написал эту программу на Go, как тут по соседству уже посоветовали. Проигрыш в скорости будет не очень существенным, а вот с кодом будет куда как приятнее иметь дело.

И да, в Go-то, как раз, поощряется заводить потоки в большом количестве. Но надо понимать, что потоки Go это не то же самое, что потоки операционной системы.
Re: Что почитать про многопоточность?
От: scf  
Дата: 16.09.19 13:07
Оценка: 6 (2)
Здравствуйте, Basil2, Вы писали:

B>Что посоветуете прочитать?


https://www.amazon.com/Art-Multiprocessor-Programming-Revised-Reprint/dp/0123973376

Обширный теоретический труд, с самого нуля и примеров "из жизни" до lock-free и аппаратных деталей синхронизации x86.

Плюсы — материал подается с нуля, содержит всю необходимую теорию для решения сложных задач синхронизации.
Минусы — примеры кода на Java, изложение не привязано ни к какому языку, так что C++ memory model придется учить отдельно, библиотеки тоже не рассматриваются
Re[3]: Что почитать про многопоточность?
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 16.09.19 15:41
Оценка: +1
Здравствуйте, Basil2, Вы писали:

B>Спасибо, присмотрюсь. Только язык видимо будет уже не С++.

Это не так важно. Концепции везде одинаковые.

K>>Я так понимаю что при воздействии игрока на мир он должен пересчитываться. Мне кажется надо обрабатывать не клиента, а запросы, а клиент это тупо некоторая модель данных.

B>Да; я просто считал что "клиент = запрос(ы)". Тут правда в предыдущем посте подкинули идею с акторами и это действительно идея. Не лочить игровой мир при модификации, а просто отправлять все изменения "хозяину мира", а он сам их проставит безо всяких лочек.
Хозяин мира будет узким местом. Надо делить мир на куски и обсчитывать изменения по кускам для всех где есть взаимодействующие объекты. Это очень похоже на то, что происходит в рендере сцены когда надо просчитать взаимодейсвия предметов, а не взаимодействующие просто отсечь. Будут те же самые деревья и т.п. По сути, всё сведётся к большому многопточному конвееру в котром бдует обрабатываться маленький кусочек мира, а артефакт обработки — дельта кусочка или нескольких.
Sic luceat lux!
Re[3]: Что почитать про многопоточность?
От: SomeOne_TT  
Дата: 16.09.19 16:10
Оценка: 4 (1)
Здравствуйте, Basil2, Вы писали:

B>Изначально я думал рискнуть и попробовать шареную память — заодно и узнать, так ли хороша защита для многопоточности в Rust. CSP я загуглил но не понял, а вот идея с акторами мне понравилась. Типа есть "хозяин мира", то есть карты на которой идет игра, и есть обработчики событий от игроков. И


CSP ооочень приятный. Я использую его реализацию в boost::fiber, но с документацией там не очень.

Про варианты можно послушать толковую лекцию от одного из парней SObjectizer'а :
Re[3]: Что почитать про многопоточность?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 17.09.19 02:58
Оценка:
Здравствуйте, Basil2, Вы писали:

B>Нет, будет скорее всего Rust.


Хороший выбор, надеюсь, у вас есть кто-то с хорошим знанием этого весьма не тривиального языка.

B>Но это не отменяет общей архитектуры. Ведь так получаются целых три слоя потоков: сетевые с соединением (плюс главный на котором сделан listen), обработчики запросов от клиентов, владельцы карт (игровых сессий). И все это как-то надо разруливать...


Думается мне, у игроделов какие-то свои паттерны широко распространенные есть. Оттуда и стоит копать.7
Re[2]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 17.09.19 12:56
Оценка:
Здравствуйте, Pzz, Вы писали:

B>>Например, я как-то сделал класс для многопоточного счетчика через операцию ++. А тимлид сказал что так нельзя, ибо стандартная сигнатура операции ++ не позволяет корректно вернуть результат в многопоточной среде, и надо использовать функцию-член типа inc(). Вот таких нюансов хотелось бы (не в смысле С++, а в смысле принципов работы с переменными).


Pzz>Интересно, а тим-лид как-то обосновал, почему ++ не подходит, или это его суеверия не велят так делать?


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

B>>И притом желательно через тред-пул, поскольку клиент=поток будет слишком накладно если много клиентов. Но выразить это в грамотную архитектуру не могу (могу наколбасить связку из мутексов и возможно будет работать), но хочется ясного понимания как это спроектировать.


Pzz>Если хочется выжать из железа 100%, это, как раз, не слишком светлая идея, выделять по потоку на клиента.


Я вроде бы так и написал.

Pzz>И да, в Go-то, как раз, поощряется заводить потоки в большом количестве. Но надо понимать, что потоки Go это не то же самое, что потоки операционной системы.


Я понимаю. Встроенный тред-пул это удобно — интересно, есть ли в Rust нечто подобное.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[4]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 17.09.19 13:02
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Хозяин мира будет узким местом.


Будет, но у нас слава богу сессионка, то есть текуших игроков мало и мир маленький.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[4]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 17.09.19 13:24
Оценка:
Здравствуйте, kaa.python, Вы писали:

B>>Нет, будет скорее всего Rust.

KP>Хороший выбор, надеюсь, у вас есть кто-то с хорошим знанием этого весьма не тривиального языка.

После С++11 выглядит очень просто: move-семантика, ссылки, лямбда-функции, RW-lock, Option<T> — всё очень знакомо. Итераторы как у LUA, обработка ошибок по Александреску, паттерн матчинг просто офигенен. Я на пробу переделал с С++ на Раст тестовое задание одной из крупных контор (типа есть модель сотрудник-отдел-фирма, надо считать их из файла и поставить каждой сущности задачу через интерфейс с консоли) — получилось без особых проблем. Даже пресловутый borrow checker сработал единственный (!) раз, когда я пытался считать строку из консоли в буфер

KP>Думается мне, у игроделов какие-то свои паттерны широко распространенные есть. Оттуда и стоит копать.


Да, уже посоветовали книжку в тему.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[3]: Что почитать про многопоточность?
От: okon  
Дата: 17.09.19 13:51
Оценка: +1
B>Да; я просто считал что "клиент = запрос(ы)". Тут правда в предыдущем посте подкинули идею с акторами и это действительно идея. Не лочить игровой мир при модификации, а просто отправлять все изменения "хозяину мира", а он сам их проставит безо всяких лочек.

Что такое "хозяин мира" ? Сервер ?
Как он проставит без лочек не совсем понятно, например два игрока одновременно шагают в одну точку, на сервер прилетает 2 запроса 2 потока обрабатывает, если не делать lock карты при изменении состояния, то могут одновременно в одной "клетке" оказаться, а должно быть что кто-то один ее занял а у второго сработала коллизия.
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Re[3]: Что почитать про многопоточность?
От: Pzz Россия https://github.com/alexpevzner
Дата: 17.09.19 13:56
Оценка: 2 (1)
Здравствуйте, Basil2, Вы писали:

B>Я понимаю. Встроенный тред-пул это удобно — интересно, есть ли в Rust нечто подобное.


Нет. Они обещали на ранних этапах развития языка, но не осилили.

В Go несколько больше, чем тред-пул. Например, если запустить Go 100500 потоков, которые что-то делают с сетью, то операционная система будет видеть количество потоков, сравнимое с количеством процессоров, и ожидание готовности будет осуществляться наиболее подходачим для системы опразом — через completion port в венде, через epoll в линухе и т.п.
Re[4]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 17.09.19 19:31
Оценка:
Здравствуйте, okon, Вы писали:


B>>Да; я просто считал что "клиент = запрос(ы)". Тут правда в предыдущем посте подкинули идею с акторами и это действительно идея. Не лочить игровой мир при модификации, а просто отправлять все изменения "хозяину мира", а он сам их проставит безо всяких лочек.


O>Что такое "хозяин мира" ? Сервер ?


Объект, который владеет картой. Условно, экземпляр класса с текущей сессией игры.

O>Как он проставит без лочек не совсем понятно, например два игрока одновременно шагают в одну точку, на сервер прилетает 2 запроса 2 потока обрабатывает, если не делать lock карты при изменении состояния, то могут одновременно в одной "клетке" оказаться, а должно быть что кто-то один ее занял а у второго сработала коллизия.


Оба запроса кидаются в очередь хозяину карты. Хозяин их вычитывает из очереди и выполняет. Лочить карту ему не нужно, ведь он ее владелец — никто другой с ней не работает.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[3]: Что почитать про многопоточность?
От: SkyDance Земля  
Дата: 17.09.19 20:33
Оценка: :)
B>Спасибо, присмотрюсь. Только язык видимо будет уже не С++.

Erlang/OTP в помощь. Да, сложно понять и осознать, но когда поймешь, обратно уже сложно вернуться. Настолько красивые и рабочие концепции!
Re[3]: Что почитать про многопоточность?
От: Masterspline  
Дата: 18.09.19 00:18
Оценка:
KP>>Я бы сказал что паттерна, основных, на данный момент два три: CSP, акторы и прямой путь в ад — шареная память. Самопальная реализация скорее зло, на которое можно идти если ты очень хорошо понимаешь что делаешь, тут, судя по вопросу, не тот случай.

B>Изначально я думал рискнуть и попробовать шареную память — заодно и узнать, так ли хороша защита для многопоточности в Rust. CSP я загуглил но не понял, а вот идея с акторами мне понравилась. Типа есть "хозяин мира", то есть карты на которой идет игра, и есть обработчики событий от игроков. И обработчики событий не пытаются сами лезть в карту под лочкой, а шлют хозяину запросы. А хозяин все делает вообще без лочек, т.к. он единственный владелец карты. По идее, в Rust тоже есть каналы (как и в Go), так что может получиться относительно нативно, без особых фреймворков.


Это означает, что каждый владыка мира может работать только на одном потоке.

B>Но это не отменяет общей архитектуры. Ведь так получаются целых три слоя потоков: сетевые с соединением (плюс главный на котором сделан listen), обработчики запросов от клиентов, владельцы карт (игровых сессий). И все это как-то надо разруливать...


Поздравляю, ты изобрел конвейер (возможно, что-то похожее Охотников называл SEDA, но это не точно). У тебя сеть работает на одном потоке, которая передает данные на другой поток (о новых подключениях или результат poll'инга (есть данные)), обработчики сетевых соединений работают на своем пуле потоков, отдают данные обработчикам событий (другой пул потоков), те отдают данные владыкам миров (каждый максимум на одном потоке, но для всех будет пул), те отдают данные обратно обработчикам событий -> сетевых подключений. Вполне рабочая архитектура.

Poller -> Читатели(писатели) <-> сериализаторы и обработчики событий <-> владыки миров (меняют мир и формируют ответ на запрос)

Я бы это реализовал на корутинах C++. Одна корутина читает и десериализует события, ставит запрос к владыке мира в очередь. Владыки работают на своем пуле. Далее корутина, которая записывает ответ от владыки в сеть.
Re[5]: Что почитать про многопоточность?
От: okon  
Дата: 18.09.19 00:54
Оценка: +2
B>Оба запроса кидаются в очередь хозяину карты. Хозяин их вычитывает из очереди и выполняет. Лочить карту ему не нужно, ведь он ее владелец — никто другой с ней не работает.

Но тогда очередь должна быть потокобезопасной, т.е. лочим не карту а очередь.
Например 2 потока пытаются одновременно добавить записи в очередь, а хозяин еще и читать ее пытается, если там не будет критической секции то может получиться непредсказуемое поведение.
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Отредактировано 18.09.2019 0:59 okon . Предыдущая версия .
Re[6]: Что почитать про многопоточность?
От: Masterspline  
Дата: 18.09.19 01:37
Оценка:
B>>Оба запроса кидаются в очередь хозяину карты. Хозяин их вычитывает из очереди и выполняет. Лочить карту ему не нужно, ведь он ее владелец — никто другой с ней не работает.

O>Но тогда очередь должна быть потокобезопасной, т.е. лочим не карту а очередь.

O>Например 2 потока пытаются одновременно добавить записи в очередь, а хозяин еще и читать ее пытается, если там не будет критической секции то может получиться непредсказуемое поведение.

Задачи эксклюзивного чтения или записи в очередь (или обращения к другому ресурсу), а также производитель-потребитель решаются стандартными средствами, которые есть в любом языке (mutex, условная переменная). Если же таких очередей и других ресурсов становится много и они зависят друг от друга, вот тогда и возникает потребность в какой-то "архитектуре" и фреймворках, реализующих эту более высокоуровневую абстракцию. Иначе тупики, гонки и глобальные блокировки, превращающие многопоточное приложение в приложение на питоне. И самое главное, при любом изменении приходится заново продумывать ВСЕ сложные зависимости, которые есть в приложении (иначе тупики, гонки и другие гейзенбаги многопоточки утекут в продакшн).

И, кстати, все (или почти) архитектуры многопоточной обработки строятся на очередях (каналах) и обработчиках этих очередей с эксклюзивным владением данными в очереди (иначе все те же зависимости по данным и шанс поймать deadlock).
Re[7]: Что почитать про многопоточность?
От: okon  
Дата: 18.09.19 08:08
Оценка: +1
Здравствуйте, Masterspline, Вы писали:

B>>>Оба запроса кидаются в очередь хозяину карты. Хозяин их вычитывает из очереди и выполняет. Лочить карту ему не нужно, ведь он ее владелец — никто другой с ней не работает.


O>>Но тогда очередь должна быть потокобезопасной, т.е. лочим не карту а очередь.

O>>Например 2 потока пытаются одновременно добавить записи в очередь, а хозяин еще и читать ее пытается, если там не будет критической секции то может получиться непредсказуемое поведение.

M>Задачи эксклюзивного чтения или записи в очередь (или обращения к другому ресурсу), а также производитель-потребитель решаются стандартными средствами, которые есть в любом языке (mutex, условная переменная).


Не совсем я понял твою мысль, инструменты то да есть, но автор я так предполагаю хочет избавится от "лочек", т.е. тех самых инструментов синхронизации.

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

Наличие в библиотеке готовых потокобезопасных очередей или списков не значит что там не будут использоваться эти самые инструменты синхронизации.
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Re[8]: Что почитать про многопоточность?
От: Masterspline  
Дата: 18.09.19 08:32
Оценка:
Здравствуйте, okon, Вы писали:

O>Здравствуйте, Masterspline, Вы писали:


B>>>>Оба запроса кидаются в очередь хозяину карты. Хозяин их вычитывает из очереди и выполняет. Лочить карту ему не нужно, ведь он ее владелец — никто другой с ней не работает.


O>>>Но тогда очередь должна быть потокобезопасной, т.е. лочим не карту а очередь.

O>>>Например 2 потока пытаются одновременно добавить записи в очередь, а хозяин еще и читать ее пытается, если там не будет критической секции то может получиться непредсказуемое поведение.

M>>Задачи эксклюзивного чтения или записи в очередь (или обращения к другому ресурсу), а также производитель-потребитель решаются стандартными средствами, которые есть в любом языке (mutex, условная переменная).


O>Не совсем я понял твою мысль, инструменты то да есть, но автор я так предполагаю хочет избавится от "лочек", т.е. тех самых инструментов синхронизации.


Насколько я понял, автор не пытается уйти от блокировок. Он ищет более высокоуровневые архитектурные подходы к разработке многопоточного кода. Моя мысль была в том, что очереди можно сделать на mutex, но если архитектура усложняется, т.е. для разных операций нужно блокировать несколько разных объектов (и в результате нужно продумать все варианты, кто и когда может заблокировать данный объект, что слишком сложно), то нужно переходить на более высокие абстракции. Но на более низком уровне они будут основаны на тех же mutex и других примитивах.

Такие архитектуры: CSP (как в Go, где общение идет через каналы, т.е. те же очереди), конвейер, который автор сам придумал в результате. Мегамонстр на акторах (который подходит для задач SCADA, где все объекты долгоживущие и каждый со своим состоянием, и который слишком сложен и не нужен, если у объектов не будет своих состояний или объекты часто создаются и уничтожаются, т.е. не подходит к задаче автора). Наверняка есть и другие.
Re[8]: Что почитать про многопоточность?
От: XuMuK Россия  
Дата: 18.09.19 08:42
Оценка:
Здравствуйте, okon, Вы писали:

O>"Карта" по сути это тот же список элементов которые содержатся в "клетке", т.е. я не вижу принципиальной разницы между работой с очередью или списком из разных потоков , в обоих случаях требуется синхронизация.

Работа с очередью — быстрые операции по перекладыванию локальных данных, работа с картой может обновлять связанные с ней объекты, лазить в базу, писать логи и делать ещё 100500 вещей. Синхронизация очереди будет дешелве и по времени и по сложности реализации.

O>Наличие в библиотеке готовых потокобезопасных очередей или списков не значит что там не будут использоваться эти самые инструменты синхронизации.

В многопоточном приложении без синхронизации не получится (lock-free очереди тоже синхронизируются), но можно минимизировать время выполнения синхронного кода и изолировать этот код от других синхронных мест (чтобы гарантировать отсутвие взаимных блокировок).
Re[9]: Что почитать про многопоточность?
От: Masterspline  
Дата: 18.09.19 09:02
Оценка:
O>>Наличие в библиотеке готовых потокобезопасных очередей или списков не значит что там не будут использоваться эти самые инструменты синхронизации.
XMK>В многопоточном приложении без синхронизации не получится (lock-free очереди тоже синхронизируются), но можно минимизировать время выполнения синхронного кода и изолировать этот код от других синхронных мест (чтобы гарантировать отсутвие взаимных блокировок).

Зачем вы рассказываете человеку, который не разобрался с многопоточкой на блокировках какие-то сложности про lockfree?
Re[9]: lock-free очереди
От: Sharov Россия  
Дата: 18.09.19 09:45
Оценка:
Здравствуйте, XuMuK, Вы писали:

XMK>(lock-free очереди тоже синхронизируются)


А можно подробнее, а то lock-free и синхронизация взаимоисключающи?
Кодом людям нужно помогать!
Re[4]: Что почитать про многопоточность?
От: MScanner  
Дата: 18.09.19 10:38
Оценка:
Здравствуйте, Pzz, Вы писали:


Pzz>В Go несколько больше, чем тред-пул. Например, если запустить Go 100500 потоков, которые что-то делают с сетью, то операционная система будет видеть количество потоков, сравнимое с количеством процессоров, и ожидание готовности будет осуществляться наиболее подходачим для системы опразом — через completion port в венде, через epoll в линухе и т.п.


причем тут Go... прога написанная на любом языке, будет обращяться к ОС за созданием потока, как будет создан поток и сколько он ресурсов сожрет это от языка мало зависит (исключим недоделки оптимизации компиляторов).

на чистом С можно создать 100500 потоков , винда выделил только один. Но это конечно зависит от того что делает поток. Если одного потока не хватит для обслуживания 100500 запросов, винда создаст дополнительный.

как там линухе ХЗ.
Re[3]: Что почитать про многопоточность?
От: MScanner  
Дата: 18.09.19 10:39
Оценка:
Здравствуйте, Basil2, Вы писали:

B>Я понимаю. Встроенный тред-пул это удобно — интересно, есть ли в Rust нечто подобное.


вы хотите этим сказать, что прога написанная на Rust создает потоки без ведома ОС ?
Re[2]: Что почитать про многопоточность?
От: MScanner  
Дата: 18.09.19 10:42
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, Basil2, Вы писали:


B>>Например, я как-то сделал класс для многопоточного счетчика через операцию ++. А тимлид сказал что так нельзя, ибо стандартная сигнатура операции ++ не позволяет корректно вернуть результат в многопоточной среде, и надо использовать функцию-член типа inc(). Вот таких нюансов хотелось бы (не в смысле С++, а в смысле принципов работы с переменными).


Pzz>Интересно, а тим-лид как-то обосновал, почему ++ не подходит, или это его суеверия не велят так делать?



интересно зачем тим-лиду обосновывать очевидные вещи ?
Re[5]: Что почитать про многопоточность?
От: Pzz Россия https://github.com/alexpevzner
Дата: 18.09.19 11:09
Оценка: +1
Здравствуйте, MScanner, Вы писали:

MS>причем тут Go... прога написанная на любом языке, будет обращяться к ОС за созданием потока, как будет создан поток и сколько он ресурсов сожрет это от языка мало зависит (исключим недоделки оптимизации компиляторов).


Стандартный сишный рантайм на любой популярной операционной системе отображает потоки C/C++ на потоки операционной системы 1:1, и это, на самом деле, очень сложно сделать по-другому. А вот стандартный рантайм Go использует один поток операционной системы для обслуживания большого количества потоков Go. И когда поток Go засыпает в ожидании завершения какой-либо блокирующейся операции, то обслуживавший его поток операционной системы не засыпает вместе с ним, а переключается на обслуживание другого потока Go (если подходящий ничейный поток найдется).

MS> на чистом С можно создать 100500 потоков , винда выделил только один. Но это конечно зависит от того что делает поток. Если одного потока не хватит для обслуживания 100500 запросов, винда создаст дополнительный.


На чистом C вообще нельзя создать никаких потоков, поток можно создать, позвав соответствующую функцию. И все пригодные для этого функции в венде в конечном итоге позовут CreateThread, которая создаст поток операционной системы.
Re[6]: Что почитать про многопоточность?
От: MScanner  
Дата: 18.09.19 11:28
Оценка: +1
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, MScanner, Вы писали:


MS>>причем тут Go... прога написанная на любом языке, будет обращяться к ОС за созданием потока, как будет создан поток и сколько он ресурсов сожрет это от языка мало зависит (исключим недоделки оптимизации компиляторов).


Pzz>А вот стандартный рантайм Go использует один поток операционной системы для обслуживания большого количества потоков Go.


рантайм Go вызывает соответсвующие функции ОС . чтобы юзать один поток для выполнения большого кол-ва запросов.

на С++ как бы есть библиотеки (boost, pplx) которые делают тоже самое (тока немного буковки другие) , в конечном счете это ведет к вызову функций ОС

C — также можно вызвать напрямую функцию ОС (winAPI например) — вот цикл из 1000 итераций в каждой итерации хотим чтобы функция F выполнялись параллельно. ОС в зависимости от функции F может на 1000 паралельных вызовов выделить 1, 50 , 100, 1000 потоков .

Рантайм любого языка дергает нужные функции ОС,


MS>> на чистом С можно создать 100500 потоков , винда выделил только один. Но это конечно зависит от того что делает поток. Если одного потока не хватит для обслуживания 100500 запросов, винда создаст дополнительный.


Pzz>На чистом C вообще нельзя создать никаких потоков, поток можно создать, позвав соответствующую функцию. И все пригодные для этого функции в венде в конечном итоге позовут CreateThread, которая создаст поток операционной системы.


если с этой точки зрения смотреть — ни один язык не может создавать никаких потоков. Так как это задача ОС.

CreateThread — позовет или нет зависит от программера. в ОС (я про винду) есть не только CreateThread для параллельного исполнения кода
Отредактировано 18.09.2019 11:30 MScanner . Предыдущая версия .
Re[10]: lock-free очереди
От: XuMuK Россия  
Дата: 18.09.19 13:50
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, XuMuK, Вы писали:


XMK>>(lock-free очереди тоже синхронизируются)


S>А можно подробнее, а то lock-free и синхронизация взаимоисключающи?


Пардон, неточно выразился. Имелась в виду логическая синхронизация выполнения кода в разных потоках.
Re[11]: lock-free очереди
От: Sharov Россия  
Дата: 18.09.19 13:53
Оценка:
Здравствуйте, XuMuK, Вы писали:

XMK> Имелась в виду логическая синхронизация выполнения кода в разных потоках.


А енто что за зверь такой?
Кодом людям нужно помогать!
Re[9]: Что почитать про многопоточность?
От: okon  
Дата: 18.09.19 13:56
Оценка:
Здравствуйте, XuMuK, Вы писали:

XMK>Здравствуйте, okon, Вы писали:


O>>"Карта" по сути это тот же список элементов которые содержатся в "клетке", т.е. я не вижу принципиальной разницы между работой с очередью или списком из разных потоков , в обоих случаях требуется синхронизация.

XMK>Работа с очередью — быстрые операции по перекладыванию локальных данных, работа с картой может обновлять связанные с ней объекты, лазить в базу, писать логи и делать ещё 100500 вещей. Синхронизация очереди будет дешелве и по времени и по сложности реализации.

Наверно соглашусь, но все же замечу 100500 вещей особенно запись в базу и лог можно делать асинхронно.


O>>Наличие в библиотеке готовых потокобезопасных очередей или списков не значит что там не будут использоваться эти самые инструменты синхронизации.

XMK>В многопоточном приложении без синхронизации не получится (lock-free очереди тоже синхронизируются), но можно минимизировать время выполнения синхронного кода и изолировать этот код от других синхронных мест (чтобы гарантировать отсутвие взаимных блокировок).

наличие возможности реализации lock-free очереди наверное единственный для меня весомый аргумент , так понимаю связный список тоже можно lock-free сделать судя по реализации которую приводят ?
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Re[12]: lock-free очереди
От: XuMuK Россия  
Дата: 19.09.19 08:36
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, XuMuK, Вы писали:


XMK>> Имелась в виду логическая синхронизация выполнения кода в разных потоках.


S>А енто что за зверь такой?


Например, поток, который изменяет глобальную карту, не будет работать пока не придут данные о действиях игрока. И наоборот, поток, который обеспечивает взаимодействие с игроком будет ждать изменений в глобальной карте, чтобы отослать их клиенту. Как этот механизм ожидания будет реализован уже не важно.
Re[10]: Что почитать про многопоточность?
От: XuMuK Россия  
Дата: 19.09.19 08:58
Оценка:
Здравствуйте, okon, Вы писали:

O>Здравствуйте, XuMuK, Вы писали:


O>наличие возможности реализации lock-free очереди наверное единственный для меня весомый аргумент

lock-free это деталь реализации, на уровне логики приложения не важно будет использована lock-free очередь или список с мьютексами и условными переменными.
Принципиальный вопрос это выбор данных, доступ к которым надо синхронизировать и разделение работы с данными по потокам. Можно обрабатывать данные о действиях пользователя в одном потоке и синхронизировать обращения к карте, а можно обрабатывать действия с картой в одном потоке, и синхронизировать работу с данными пользователя. На мой взгляд второй вариант будет предпочтительнее, т.к. карта здесь выступает в качестве глобальной переменной к которой обращаются все пользователи, а данные от пользователя и к пользователю локализованы в обработчике соединения.

O>так понимаю связный список тоже можно lock-free сделать судя по реализации которую приводят ?

Можно готовый взять, но речь не об этом.
Re[6]: Что почитать про многопоточность?
От: AlexGin Беларусь  
Дата: 19.09.19 10:52
Оценка:
Здравствуйте, okon, Вы писали:

O>Но тогда очередь должна быть потокобезопасной, т.е. лочим не карту а очередь.

O>Например 2 потока пытаются одновременно добавить записи в очередь, а хозяин еще и читать ее пытается, если там не будет критической секции то может получиться непредсказуемое поведение.
+100500
Критическая секция или мьютекс — здесь просто необходим для синхронизации потоков!
Re[4]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 20.09.19 15:45
Оценка:
Здравствуйте, Masterspline, Вы писали:

M>Это означает, что каждый владыка мира может работать только на одном потоке.


Да, но это проблема только если мир один, как в WoW или в Eve. А если это сессионка, типа WoT, то там одновременных миров заведомо больше чем ядер, так что по любому будет не хуже.

M>Я бы это реализовал на корутинах C++. Одна корутина читает и десериализует события, ставит запрос к владыке мира в очередь. Владыки работают на своем пуле. Далее корутина, которая записывает ответ от владыки в сеть.


При всей моей любви к С++, многопоточность там сделали очень угребищно. Std::thread c его terminate и std::async, которой вовсе не асинк даже в случае с std::async(std::async::async), это просто что-то с чем-то. Как-то не хочется в эту трясину лезть.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[6]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 20.09.19 17:51
Оценка:
Здравствуйте, okon, Вы писали:

O>Но тогда очередь должна быть потокобезопасной, т.е. лочим не карту а очередь.


Само собой. Но такая очередь — это уже готовая и простая конструкция, ее можно просто взять и использовать, почти без шансов накосячить.

O>Например 2 потока пытаются одновременно добавить записи в очередь, а хозяин еще и читать ее пытается, если там не будет критической секции то может получиться непредсказуемое поведение.


Скорее всего там еще и condition variable будет.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[4]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 20.09.19 17:54
Оценка:
Здравствуйте, MScanner, Вы писали:

B>>Я понимаю. Встроенный тред-пул это удобно — интересно, есть ли в Rust нечто подобное.

MS>вы хотите этим сказать, что прога написанная на Rust создает потоки без ведома ОС ?

В Rust еще не знаю, а в Go это типа суперфича языка. Ты хоть тысячи потоков создаешь, а Go сам раскладывает их в несколько потоков операционки.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[5]: Что почитать про многопоточность?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 21.09.19 12:26
Оценка:
Здравствуйте, Basil2, Вы писали:

B>В Rust еще не знаю, а в Go это типа суперфича языка. Ты хоть тысячи потоков создаешь, а Go сам раскладывает их в несколько потоков операционки.


В Rust зеленых потоков не осилили, изначально такая фича была. Сейчас там 1:1 через threads. Зато каналы осилили, что уже большой шаг вперед я считаю.
Re[5]: Что почитать про многопоточность?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 21.09.19 12:35
Оценка:
Здравствуйте, Basil2, Вы писали:

B>При всей моей любви к С++, многопоточность там сделали очень угребищно. Std::thread c его terminate и std::async, которой вовсе не асинк даже в случае с std::async(std::async::async), это просто что-то с чем-то. Как-то не хочется в эту трясину лезть.


Да ладно, все не так плохо, не хуже чем в Rust, по большому счету, разве что нет канала, но при том, что канал — это потоко-безопасная очередь, то соорудить его подобие не сложно, ведь r/w синхронизация еще с C++11 имеется. Понятно, что не Go по возможностям, но тоже хорошо.

Кроме того, комбинации promise/future для многих задач вполне достаточно, лично меня печалит то, что о необходимости when_any/when_all задумались только в рамках concurrency TS.
Отредактировано 21.09.2019 12:48 kaa.python . Предыдущая версия .
Re[3]: Что почитать про многопоточность?
От: Ops Россия  
Дата: 21.09.19 21:05
Оценка: +1
Здравствуйте, MScanner, Вы писали:

Pzz>>Интересно, а тим-лид как-то обосновал, почему ++ не подходит, или это его суеверия не велят так делать?



MS>интересно зачем тим-лиду обосновывать очевидные вещи ?


Кому очевидные?
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[3]: Что почитать про многопоточность?
От: Ops Россия  
Дата: 22.09.19 08:19
Оценка:
Здравствуйте, Basil2, Вы писали:

B>Конечно. ++ возвращает ссылку, а она невалидна в многопоточной среде. А если возвращать значение, то нарушится стандартная сигнатура, что тоже нехорошо.


А много существует сценариев, когда от атомарной переменной в таком контексте требуется именно ссылка, а не значение?
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[6]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 22.09.19 10:41
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>В Rust зеленых потоков не осилили, изначально такая фича была.


Они пишут что не сделали осознанно, т.к. сильно раздувает рантайм.

KP>Зато каналы осилили, что уже большой шаг вперед я считаю.


Да, я на каналах планирую делать.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[6]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 22.09.19 10:49
Оценка:
Здравствуйте, kaa.python, Вы писали:

B>>При всей моей любви к С++, многопоточность там сделали очень угребищно. Std::thread c его terminate и std::async, которой вовсе не асинк даже в случае с std::async(std::async::async), это просто что-то с чем-то. Как-то не хочется в эту трясину лезть.


KP>Да ладно, все не так плохо, не хуже чем в Rust, по большому счету,


Я многопоточность Rust только изучаю, но пока там не видится тех жоп, которые аж by design есть в С++ примитивах. Причем жопы так и были задуманы, я полдня не мог понять, почему два async() не выполняются асинхронно.

KP>разве что нет канала, но при том, что канал — это потоко-безопасная очередь, то соорудить его подобие не сложно, ведь r/w синхронизация еще с C++11 имеется.


Несложно, однако в Rust каналы — это дефолтный способ обеспечения синхронности.

KP>Понятно, что не Go по возможностям, но тоже хорошо.


А в Go есть что-то кроме каналов и встроенного тред-пула?
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[4]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 22.09.19 10:55
Оценка:
Здравствуйте, Ops, Вы писали:

B>>Конечно. ++ возвращает ссылку, а она невалидна в многопоточной среде. А если возвращать значение, то нарушится стандартная сигнатура, что тоже нехорошо.


Ops>А много существует сценариев, когда от атомарной переменной в таком контексте требуется именно ссылка, а не значение?


Их может и вообще не быть. Но стандартная сигнатура оператора ++ определена как
T& operator++();

а нарушать их считается дурным тоном.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[5]: Что почитать про многопоточность?
От: Ops Россия  
Дата: 22.09.19 11:03
Оценка: 1 (1) +1
Здравствуйте, Basil2, Вы писали:

B>Их может и вообще не быть. Но стандартная сигнатура оператора ++ определена как

B>
B>T& operator++();
B>

B>а нарушать их считается дурным тоном.

Это все предрассудки, тем более что в стандартной библиотеке вполне себе нарушают, я рядом привел ссылку. Одно дело, когда это может создать реальные трудности, другое — религиозные причины.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[6]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 22.09.19 11:23
Оценка:
Здравствуйте, Ops, Вы писали:

B>>Их может и вообще не быть. Но стандартная сигнатура оператора ++ определена как

B>>
B>>T& operator++();
B>>

B>>а нарушать их считается дурным тоном.

Ops>Это все предрассудки, тем более что в стандартной библиотеке вполне себе нарушают, я рядом привел ссылку.


Да, в атомиках-то учли эту проблему и сигнатуру поменяли. Дык изначальный-то пост именно про это и был — что есть нюансы, причем весьма неочевидные и настолько же серьезные.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[7]: Что почитать про многопоточность?
От: Ops Россия  
Дата: 22.09.19 11:38
Оценка: +1
Здравствуйте, Basil2, Вы писали:

B>Да, в атомиках-то учли эту проблему и сигнатуру поменяли. Дык изначальный-то пост именно про это и был — что есть нюансы, причем весьма неочевидные и настолько же серьезные.


Так я по конкретному вопросу из начального поста

Например, я как-то сделал класс для многопоточного счетчика через операцию ++. А тимлид сказал что так нельзя, ибо стандартная сигнатура операции ++ не позволяет корректно вернуть результат в многопоточной среде, и надо использовать функцию-член типа inc().

В чем отличие твоего класса от атомика (вероятно, урезанного), что нельзя сделать этот момент так же, как там? Аргумент "не та сигнатура" кажется мне исключительно религиозным, по крайней мере пока нет реальных, не синтетических, примеров, когда требуется именно ссылочный тип в таком контексте.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[7]: Что почитать про многопоточность?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 22.09.19 13:38
Оценка:
Здравствуйте, Basil2, Вы писали:

KP>>Зато каналы осилили, что уже большой шаг вперед я считаю.

B>Да, я на каналах планирую делать.

Тут надо быть довольно осторожным. Судя по начальному вопросу четкого понимания что делать нет, но Rust не дает никаких бонусов кроме каналов относительно C++, при этом по сложности вобщем-то сопоставим. Может все-так Go?
Re[7]: Что почитать про многопоточность?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 22.09.19 13:44
Оценка:
Здравствуйте, Basil2, Вы писали:

B>>>При всей моей любви к С++, многопоточность там сделали очень угребищно. Std::thread c его terminate и std::async, которой вовсе не асинк даже в случае с std::async(std::async::async), это просто что-то с чем-то. Как-то не хочется в эту трясину лезть.


Ничего не понял... std::async(std::async::async) гарантирует выполнение в отдельном потоке. Разве нет?

Asynchronous: Launches a new thread to call fn (as if a thread object is constructed with fn and args as arguments, and accessing the shared state of the returned future joins it).


Тут скорее не угребищно сделали, а мало сделали, но очень грамотно, что несколько про другое.

B>Я многопоточность Rust только изучаю, но пока там не видится тех жоп, которые аж by design есть в С++ примитивах. Причем жопы так и были задуманы, я полдня не мог понять, почему два async() не выполняются асинхронно.


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

B>Несложно, однако в Rust каналы — это дефолтный способ обеспечения синхронности.


Который а) не бесплатен, б) не отменяет того, что все потоки нативные и с ними надо уметь работать. Так же как и в C++.

B>А в Go есть что-то кроме каналов и встроенного тред-пула?


О, тут много что есть. Во-первый, тут есть чудесная система модулей запрещающая циклические зависимости, во-вторых, есть отличные интерфейсы, ну и в-третьих, есть великолепная читабельность кода, ни с чем не сравнимая.
Re[5]: Что почитать про многопоточность?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 23.09.19 01:54
Оценка:
Здравствуйте, Basil2, Вы писали:

B>Их может и вообще не быть. Но стандартная сигнатура оператора ++ определена как

B>
B>T& operator++();
B>

B>а нарушать их считается дурным тоном.

А разве не так?
T& T::operator++();
T T::operator++(int);


https://en.cppreference.com/w/cpp/language/operator_incdec

Я не часто операторы реализую, но когда недавно писал итератор, то обратил внимание на тот факт, что ссылка возвращается только в одном случае, во втором по начению.
Re[7]: Что почитать про многопоточность?
От: andmed  
Дата: 23.09.19 06:08
Оценка: 4 (1)
B>А в Go есть что-то кроме каналов и встроенного тред-пула?

неплохой обзор для си++шников
https://github.com/golang/go/wiki/GoForCPPProgrammers
и туда же https://www.andmed.org для джавистов
Re[6]: Что почитать про многопоточность?
От: AndrewJD США  
Дата: 23.09.19 14:48
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>Кроме того, комбинации promise/future для многих задач вполне достаточно,


promise/future из стандартной библиотеки на данный момент ни на что кроме hello world не годен:
  1. Нет возможности добаваить continuation. Т.е. он имеет изначально сломанный интерфейс. И без concurrency TS, без executors его не исправить. Но concurrency TS — это 2023 в лучшем случае.
  2. Большой оверхед. На последнем CppCon было несколько докладов, где предлагались свои варианты future которые используют обьекты синхронизации только когда это действительно нужно.

KP>лично меня печалит то, что о необходимости when_any/when_all задумались только в рамках concurrency TS.

Даже в бусте when_any/when_all нормально сделать не смогли. Создают вспомогательные потоки и делают ожидание в них. И как выполнить например 1000 ожиданий?
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re: Что почитать про многопоточность?
От: reversecode google
Дата: 23.09.19 15:05
Оценка:
мухи, котлеты и еще вишенка на блюдечке

> многопоточность, сетевой сервер MMO, использовал C++ но без привязки к языку ....


я вот реально не понимаю людей которые с возможно большим опытом в разработке не могут сформулировать вопрос

многопоточность и примитивы синхронизации начинаются с изучения устройства и работы CPU и ОС

это как раз то что без привязки к языку изучается
дальше в каждом языке по разному. Erlang, Go, Java, C# и тот же C++
надо изучать отдельно
в них все по разному

дальше идет сетевая архитектура и применительно к языкам описанных выше от нее к ним большой разрыв

т.е. опять нужно изучать совершенно другое

если у вас нет опыта сетевой разработки, то даже просто что то почитав, вы в этот поезд еще долго не запрыгните
и определитесь наконец то с самым главным на мой взгляд, языком реализации
Re[2]: Что почитать про многопоточность?
От: so5team https://stiffstream.com
Дата: 24.09.19 08:26
Оценка: 10 (1)
Здравствуйте, kaa.python, Вы писали:

KP>Я бы сказал что паттерна, основных, на данный момент два три: CSP, акторы и прямой путь в ад — шареная память.


Таки есть еще task-based подход (TBB TaskGraph, cpp-taskflow, отчасти HPX). Хотя можно еще и реактивное программирование помянуть. Но в контексте задачи топик-стартера разве что CSP и акторы имеет смысл рассматривать.
Re[8]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 24.09.19 09:59
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>Ничего не понял... std::async(std::async::async) гарантирует выполнение в отдельном потоке. Разве нет?


Ха-ха-ха. Код

std::async(std::async::async, []{ print("1"); sleep(1000); print("2"); });
std::async(std::async::async, []{ print("3"); sleep(1000); print("4"); });

Что напечатает?

B>>А в Go есть что-то кроме каналов и встроенного тред-пула?

KP>О, тут много что есть. Во-первый, тут есть чудесная система модулей запрещающая циклические зависимости, во-вторых, есть отличные интерфейсы, ну и в-третьих, есть великолепная читабельность кода, ни с чем не сравнимая.

Я в смысле многопоточности, а не языка вообще.

if err != nil {
    return err
}

Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[8]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 24.09.19 10:02
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>Тут надо быть довольно осторожным. Судя по начальному вопросу четкого понимания что делать нет, но Rust не дает никаких бонусов кроме каналов относительно C++, при этом по сложности вобщем-то сопоставим. Может все-так Go?


А смысл? Rust превосходит Go практически во всем: скорость, надежность, мощность, выразительность, обработка ошибок. На Go проще запиливать веб-сервисы, за счет чего его доля быстро растет, т.к. он заменяет одновременно Python, Node.JS, C#, Perl и PHP. Но мне больше нравится системная тема.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[9]: Что почитать про многопоточность?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 24.09.19 10:06
Оценка:
Здравствуйте, Basil2, Вы писали:

B>Ха-ха-ха. Код


B>
B>std::async(std::async::async, []{ print("1"); sleep(1000); print("2"); });
B>std::async(std::async::async, []{ print("3"); sleep(1000); print("4"); });
B>

B>Что напечатает?

1234 напечатает. Но это не баг, это фича... как бы.

B>
B>if err != nil {
B>    return err
B>}
B>

B>)

И? Явная обработка ошибки. Ты просто из C++ мира смотришь на что-то новое и кажется странно, но это не так, это просто новое и не на ровном месте возникшее.
Re[6]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 24.09.19 10:08
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>А разве не так?

KP>
KP>T& T::operator++();
KP>T T::operator++(int);
KP>


Так, но основной-то первый вариант.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[9]: Что почитать про многопоточность?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 24.09.19 10:17
Оценка:
Здравствуйте, Basil2, Вы писали:

B>А смысл? Rust превосходит Go практически во всем: скорость, надежность, мощность, выразительность, обработка ошибок. На Go проще запиливать веб-сервисы, за счет чего его доля быстро растет, т.к. он заменяет одновременно Python, Node.JS, C#, Perl и PHP. Но мне больше нравится системная тема.


Это в тебе снобизм С++ разработчика говорит, меня так же крыло по началу. На деле, Rust, C++ и куча других языков проигрывает вот этому тупому и нелепому Го в простоте кода и читабельности. А это критично для любого проекта, у которого предполагается более менее долгий цикл поддержки и развития.
Re[7]: Что почитать про многопоточность?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 24.09.19 10:23
Оценка:
Здравствуйте, Basil2, Вы писали:

B>Здравствуйте, kaa.python, Вы писали:


KP>>А разве не так?

KP>>
KP>>T& T::operator++();
KP>>T T::operator++(int);
KP>>


B>Так, но основной-то первый вариант.


Как первый? Разве i++ (второй вариант) не чаще используется чем ++i (первый вариант) ? Ну и, как сказали выше, это просто вкусовщина, и семантика может использоваться любая.
Отредактировано 24.09.2019 13:16 kaa.python . Предыдущая версия . Еще …
Отредактировано 24.09.2019 13:16 kaa.python . Предыдущая версия .
Re[7]: Что почитать про многопоточность?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 26.09.19 02:13
Оценка:
Здравствуйте, AndrewJD, Вы писали:

AJD>Даже в бусте when_any/when_all нормально сделать не смогли. Создают вспомогательные потоки и делают ожидание в них. И как выполнить например 1000 ожиданий?


Что-то мне интересно стало, а нет сведений как это же самое в Rust реализовано?
Re[10]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 28.09.19 15:00
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>1234 напечатает. Но это не баг, это фича... как бы.


Очень верно подмечено.

B>>
B>>if err != nil {
B>>    return err
B>>}
B>>

KP>И? Явная обработка ошибки. Ты просто из C++ мира смотришь на что-то новое и кажется странно, но это не так, это просто новое и не на ровном месте возникшее.

В данному случае я смотрю из мира Rust
Там код
val, err := foo();
if err != nil {
    return err;
}

превращается в
let val = foo()?;

Возврат нескольких значений в Go это _очень_ большой шаг по сравнению с С++, где приходилось извращаться с выходными параметрами и предварительным объявлением переменных (без возможности, например, объявить константу). Но в плане читабельности Go еще есть куда расти
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[10]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 28.09.19 15:05
Оценка: :)
Здравствуйте, kaa.python, Вы писали:

B>>А смысл? Rust превосходит Go практически во всем: скорость, надежность, мощность, выразительность, обработка ошибок. На Go проще запиливать веб-сервисы, за счет чего его доля быстро растет, т.к. он заменяет одновременно Python, Node.JS, C#, Perl и PHP. Но мне больше нравится системная тема.


KP>На деле, Rust, C++ и куча других языков проигрывает вот этому тупому и нелепому Го в простоте кода и читабельности. А это критично для любого проекта, у которого предполагается более менее долгий цикл поддержки и развития.


Я бы не называл Го тупым и нелепым (нелепый — это JavaScript, а тупых языков я пожалуй и не знаю, из мейнстримовых). У Гугла отлично получилось сделать простой и мощный язык, пусть и несколько разрозненный. Это как автомат Калашникова, условно. Да, для рядовых бойцов это самое то. Но если ты в спецназе, то там есть более подходящее оружие.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[8]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 28.09.19 15:12
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>>>А разве не так?

KP>>>
KP>>>T& T::operator++();
KP>>>T T::operator++(int);
KP>>>


B>>Так, но основной-то первый вариант.

KP>Как первый?

Так — потому что второй вариант канонически реализуется паттерном через первый:
T T::operator++(int) {
   T temp(t);
   t++;
   return temp;
}

KP>Разве i++ (второй вариант) не чаще используется чем ++i (первый вариант) ?
Это было до появления итераторов. Теперь положено использовать ++i.

KP>Ну и, как сказали выше, это просто вкусовщина, и семантика может использоваться любая.

Это не вкусовщина, а серьезный performance impact, так как вторая операция значительно медленнее, да еще и в цикле (если речь не о целочисленных переменных).
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[11]: Что почитать про многопоточность?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 28.09.19 23:04
Оценка:
Здравствуйте, Basil2, Вы писали:

B>Возврат нескольких значений в Go это _очень_ большой шаг по сравнению с С++, где приходилось извращаться с выходными параметрами и предварительным объявлением переменных (без возможности, например, объявить константу). Но в плане читабельности Go еще есть куда расти


Ты всерьез считаешь, что выискивать знак вопроса в конце функции (при том что они могут быть цепочкой выстроены) — это большой шаг вперед в пользу читабельности?
Re[9]: Что почитать про многопоточность?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 28.09.19 23:09
Оценка:
Здравствуйте, Basil2, Вы писали:

KP>>Ну и, как сказали выше, это просто вкусовщина, и семантика может использоваться любая.

B>Это не вкусовщина, а серьезный performance impact, так как вторая операция значительно медленнее, да еще и в цикле (если речь не о целочисленных переменных).

А ты замерять реально пробовал, на не синтетических тестах? Хоть раз видел что бы из за оператора ++ были тормоза? По мне так это типичная страсть C++ разработчика к оптимизации того, что оптимизировать не требуется.
Re[11]: Что почитать про многопоточность?
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 29.09.19 03:50
Оценка: :)
Здравствуйте, Basil2, Вы писали:

B>Я бы не называл Го тупым и нелепым (нелепый — это JavaScript, а тупых языков я пожалуй и не знаю, из мейнстримовых). У Гугла отлично получилось сделать простой и мощный язык, пусть и несколько разрозненный. Это как автомат Калашникова, условно. Да, для рядовых бойцов это самое то. Но если ты в спецназе, то там есть более подходящее оружие.


Упс, извините, не знал что к спецназовцу со своим на вным видением лезу. Я больше не буду
Re[12]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 29.09.19 10:12
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>Ты всерьез считаешь, что выискивать знак вопроса в конце функции (при том что они могут быть цепочкой выстроены) —

Зачем его выискивать?!

KP>это большой шаг вперед в пользу читабельности?

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

Есть кстати пара вопросов в тему:

1. Как в Go прочитать значение переменной под лочкой?

2. Чем Go лучше C#?
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Отредактировано 29.09.2019 10:33 Basil2 . Предыдущая версия .
Re[10]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 29.09.19 10:14
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>А ты замерять реально пробовал, на не синтетических тестах? Хоть раз видел что бы из за оператора ++ были тормоза? По мне так это типичная страсть C++ разработчика к оптимизации того, что оптимизировать не требуется.


Зачем? Использование i++ это заведомая пессимизация по сравнению с ++i. Да, глупо оптимизировать без причины, но пессимизировать не менее глупо.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[12]: Что почитать про многопоточность?
От: Basil2 Россия https://starostin.msk.ru
Дата: 29.09.19 10:16
Оценка:
Здравствуйте, kaa.python, Вы писали:

B>>Я бы не называл Го тупым и нелепым (нелепый — это JavaScript, а тупых языков я пожалуй и не знаю, из мейнстримовых). У Гугла отлично получилось сделать простой и мощный язык, пусть и несколько разрозненный. Это как автомат Калашникова, условно. Да, для рядовых бойцов это самое то. Но если ты в спецназе, то там есть более подходящее оружие.


KP>Упс, извините, не знал что к спецназовцу со своим на вным видением лезу. Я больше не буду


Я только учусь, но тем не менее аналогия очень верна. Го, как и калаш, станет очень популярным, это несомненно. Просто популярное не значит самое лучшее.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.