Предварительное уточнение, я с std::sync давно не работал напрямую и использовал в основном из tokio асинхронные варианты. Относительно недавно в основной раст добавили каналы из crossbeam, которые считались лучшей версией, нежели основные. Старые были без мьютексов, но думаю это не актуально. https://doc.rust-lang.org/1.66.0/src/std/sync/mpsc/mpsc_queue.rs.html
По поводу того, что вы скинули. я бегло глянул, где оно там используется. Во первых там есть 2 варианта каналов: bounded и unbounded В bounded случае канал ограничен размером и используется array::Channel (ну или zero::Channel, если ограничить в ноль размер), и SyncWaker там используется, чтобы разбудить тех отправителей, которые были добавлены в очередь, когда канал был забит. В обоих случаях SyncWaker используется, чтобы разбудить получателей, если канал был пустым и кто-то туда что-то прислал. То есть это некая оптимизация для пустых (или полных в bounded случае) каналов.
Сама отсылка в очередь (и забор из нее) делается через cas, спинлок и вот это вот все. это вы можете посмотреть в start_send(start_recv) методах соответствующих Channel (array, list и zero).
Заодно глянул как оно там в tokio. Eсли в std(после мерджа crossbeam) все сделано на основе mpmс, просто при создании создается всего один получатель и mpmc превращается в mpsc, то в токио оно сразу идет как mpsc. Поэтому там нет таких же Waker для получателей, там идет один AtomicWaker и он без мьютексов, а на атомиках (как можно понять по названию). А для отправителей, да, идет семафор, но исключительно для задач ограничения размера канала. Сама же отправка точно так же идет через cas.
Итоги: мьютексы (и семафоры) используются, тут вы правы. Используются ли они для реализации самой очереди и разрешения конфликтов в ней при вставке или заборе очередного сообщения? Нет, не используются. Для чего они используются? Для оптимизации случаев пустых или переполненных каналов. Можно ли без них? Я не знаю.
Спасибо за то, что указали на это и дали повод чуть подробнее изучить.
Так я нигде и не утверждал, что они быстрее мьютексов. Более того я прекрасно понимаю, что оно в негативном сценарии в отличие от мьютекса еще и проц будет жрать как не в себя. Разница только в том, что в одном случае все будет намертво висеть, если ресурс занят, а в другом случае возможны варианты. Реальный сценарий реальному сценарию рознь. Если втупую взять какую-то общую структуру, которая шарится на много потоков и поменять мьютексы на lock-free, то почти наверняка оно хуже и будет. Все системы с обменом сообщениями, с которыми я работал и работаю подразумевают, что таких глобальных данных под мьютексом, в которые ломятся все кому не лень, нужно избегать и заменять на отдельные сообщения между отдельными потоками. В некоторых случаях у вас даже возможности такой не будет пошарить данные, например в эрланге(ну формально, конечно, можно и там извратиться, но это надо прям очень сильно захотеть). Но благодаря этому многопоточная разработка становится в разы проще и понятнее и помогает избежать кучи проблем. Об этом (как мне показалось) и было оригинальное сообщение в треде. Ну и да, даже очереди с мьютексами (а то и вообще с RWLock) под капотом с точки зрения отсутствия возможности отстрелить себе ногу в разы лучше, чем голые мьютексы. Да, оно будет очевидно медленнее, но избавит от кучи головной боли, о которой в частности и написана статья.
По поводу видео, его я посмотреть не успел, но заголовок говорит о том, что там описывается mpmc, мои примеры выше работают либо в варианте mpsc, либо в варианте spsc вообще.
Дождаться-то как раз и несложно. Если у вас такой огромный поток сообщений, то конкуренция будет на вставку, а консьюмер в спинлок попадать не будет. Ну разве что консьюмер выгребает сообщения настолько быстро, что длина очереди в среднем нулю равна.
Все эти очереди потокобезопасны и грин треды тут вообще ни при чем. Тем более что зачастую грин треды вполне себе на обычных потоках делаются (шедулеры в эрланге или какой нибудь тредпул в токио в расте).
Ну и там нет примитива исключительного доступа как правило, в этом и смысл lock-free. Ну то есть нет такого, чтобы какой-то поток залочил себе запись, а все остальные ждут, когда он закончит.
Атомики и мьютексы вообще несравнимые вещи и то как они реализованы очень сильное значение имеет.
Я не знаю, что вы подразумеваете под очередями сообщений, но все известные мне и широко используемые очереди сообщений, которые используются для общения именно между «тредаии», мьютексов не используют, насколько я знаю. Я про эрланговые мейлбоксы, растовые mpsc и гошные каналы. Ну и «самопальные» очереди в тех случаях, где оно не встроено, тоже пилят на всяких атомиках и прочем обычно.
И в Google Play и в AppStore прекрасно работают схемы с подписями чеков приватным ключом стора и проверкой их без непосредственного обращения к самому стору со стороны бэкенда. Это в некоторых случаях, правда, добавляет других проблем.
Но «два» и «2» можно рассматривать как равнозначные?
Только в рамках русского языка. Тому, кто не знает русский язык, понятие 2 может быть знакомо, а вот слово «два» нет. Более того, ему и цифра 2 может быть незнакома, а до двух сосчитать он сможет. Но я уже выше писал, что существуют народы, которые и этого не смогут.
Значит теперь уже физического… а раньше было реального.
Давайте определимся с терминологией, что вы подразумеваете под первым и под вторым?
И даже если вам не нравится термин «физический», то и реального объекта «2» не появилось, появилась другая рука.
К двум яблокам на столе можно прибавить 3 груши, чтобы получилось 5 фруктов.
Как из 5 фруктов выделить непосредственно физическийреальный объект «5»? Но вообще хорошо, что тут вы сами двигаетесь в сторону абстракции. Если прибавить 2 грузовика к 3 стаканам сока, то 5 чего получится?
Потому что все, что вы описывали, не является именно числом 2. Нет физического объекта — который является числом 2.
Если взять пример с двумя руками — тут все очевидно, как были руки, так и остались, отдельного физического объекта 2 не появилось.
Если рассматривать пиксели на экране или звуковые волны или что угодно вы там используете для описания числа 2, то это тоже не работает вот почему: Если сложить число 2 с числом 3 — должно получиться число 5, а у вас получится какая-то мешанина пикселей или звуковых колебаний.
Откуда такой замечательный вывод? Математика вообще по своей сути набор различных абстракций, причем далеко не всем из них удается сопоставить реальные объекты. Если вы уйдете чуть дальше арифметики — вы это поймете.
Еще раз. Есть народы, у которых нет этой абстракции. То есть 2 дерева физически существуют, а числа 2 нет. Да и в вашей же цитате написано, что число — это понятие.
Следуя вашей логике слово — это тоже реальный объект, потому что в той или иной форме он существует у всех народов?
Число — это абстрактное понятие, а не реальный объект. 2 руки — это 2 руки, а не число 2. Щупая 2 руки вместо одной, вы будете щупать все так же руки, а не число 2.
Больше того скажу, в Полинезии существуют народы, которые не знают данной абстракции. У них натурально для каждого существительного есть отдельные слова для разного количества. То есть отдельное слово для одной овцы, отдельное слово для двух овец. Аналогично с деревьями. И они не находят общих признаков у двух овец и двух деревьев.
Предварительное уточнение, я с std::sync давно не работал напрямую и использовал в основном из tokio асинхронные варианты. Относительно недавно в основной раст добавили каналы из crossbeam, которые считались лучшей версией, нежели основные. Старые были без мьютексов, но думаю это не актуально.
https://doc.rust-lang.org/1.66.0/src/std/sync/mpsc/mpsc_queue.rs.html
По поводу того, что вы скинули. я бегло глянул, где оно там используется.
Во первых там есть 2 варианта каналов: bounded и unbounded
В bounded случае канал ограничен размером и используется array::Channel (ну или zero::Channel, если ограничить в ноль размер),
и SyncWaker там используется, чтобы разбудить тех отправителей, которые были добавлены в очередь, когда канал был забит.
В обоих случаях SyncWaker используется, чтобы разбудить получателей, если канал был пустым и кто-то туда что-то прислал.
То есть это некая оптимизация для пустых (или полных в bounded случае) каналов.
Сама отсылка в очередь (и забор из нее) делается через cas, спинлок и вот это вот все.
это вы можете посмотреть в start_send(start_recv) методах соответствующих Channel (array, list и zero).
Заодно глянул как оно там в tokio. Eсли в std(после мерджа crossbeam) все сделано на основе mpmс, просто при создании создается всего один получатель и mpmc превращается в mpsc, то в токио оно сразу идет как mpsc. Поэтому там нет таких же Waker для получателей, там идет один AtomicWaker и он без мьютексов, а на атомиках (как можно понять по названию). А для отправителей, да, идет семафор, но исключительно для задач ограничения размера канала. Сама же отправка точно так же идет через cas.
Итоги: мьютексы (и семафоры) используются, тут вы правы. Используются ли они для реализации самой очереди и разрешения конфликтов в ней при вставке или заборе очередного сообщения? Нет, не используются. Для чего они используются? Для оптимизации случаев пустых или переполненных каналов. Можно ли без них? Я не знаю.
Спасибо за то, что указали на это и дали повод чуть подробнее изучить.
Так я нигде и не утверждал, что они быстрее мьютексов. Более того я прекрасно понимаю, что оно в негативном сценарии в отличие от мьютекса еще и проц будет жрать как не в себя. Разница только в том, что в одном случае все будет намертво висеть, если ресурс занят, а в другом случае возможны варианты.
Реальный сценарий реальному сценарию рознь. Если втупую взять какую-то общую структуру, которая шарится на много потоков и поменять мьютексы на lock-free, то почти наверняка оно хуже и будет. Все системы с обменом сообщениями, с которыми я работал и работаю подразумевают, что таких глобальных данных под мьютексом, в которые ломятся все кому не лень, нужно избегать и заменять на отдельные сообщения между отдельными потоками. В некоторых случаях у вас даже возможности такой не будет пошарить данные, например в эрланге(ну формально, конечно, можно и там извратиться, но это надо прям очень сильно захотеть). Но благодаря этому многопоточная разработка становится в разы проще и понятнее и помогает избежать кучи проблем.
Об этом (как мне показалось) и было оригинальное сообщение в треде. Ну и да, даже очереди с мьютексами (а то и вообще с RWLock) под капотом с точки зрения отсутствия возможности отстрелить себе ногу в разы лучше, чем голые мьютексы. Да, оно будет очевидно медленнее, но избавит от кучи головной боли, о которой в частности и написана статья.
По поводу видео, его я посмотреть не успел, но заголовок говорит о том, что там описывается mpmc, мои примеры выше работают либо в варианте mpsc, либо в варианте spsc вообще.
Дождаться-то как раз и несложно. Если у вас такой огромный поток сообщений, то конкуренция будет на вставку, а консьюмер в спинлок попадать не будет. Ну разве что консьюмер выгребает сообщения настолько быстро, что длина очереди в среднем нулю равна.
Разговор начался с того, что было указано, что без мьютексов это невозможно. Это возможно. Плюсы и минусы этих механизмов - это уже отдельный вопрос.
Все эти очереди потокобезопасны и грин треды тут вообще ни при чем. Тем более что зачастую грин треды вполне себе на обычных потоках делаются (шедулеры в эрланге или какой нибудь тредпул в токио в расте).
Ну и там нет примитива исключительного доступа как правило, в этом и смысл lock-free. Ну то есть нет такого, чтобы какой-то поток залочил себе запись, а все остальные ждут, когда он закончит.
Атомики и мьютексы вообще несравнимые вещи и то как они реализованы очень сильное значение имеет.
Я не знаю, что вы подразумеваете под очередями сообщений, но все известные мне и широко используемые очереди сообщений, которые используются для общения именно между «тредаии», мьютексов не используют, насколько я знаю. Я про эрланговые мейлбоксы, растовые mpsc и гошные каналы. Ну и «самопальные» очереди в тех случаях, где оно не встроено, тоже пилят на всяких атомиках и прочем обычно.
Lock-free queue
И в Google Play и в AppStore прекрасно работают схемы с подписями чеков приватным ключом стора и проверкой их без непосредственного обращения к самому стору со стороны бэкенда. Это в некоторых случаях, правда, добавляет других проблем.
Открыл оригинал, он как раз в 18 году и написан, но редакция Rust 2018 еще не вышла.
extern crate уже сто лет как не требуется писать, где-то года с 2018 если быть точным.
Только в рамках русского языка. Тому, кто не знает русский язык, понятие 2 может быть знакомо, а вот слово «два» нет. Более того, ему и цифра 2 может быть незнакома, а до двух сосчитать он сможет. Но я уже выше писал, что существуют народы, которые и этого не смогут.
Давайте определимся с терминологией, что вы подразумеваете под первым и под вторым?
И даже если вам не нравится термин «физический», то и реального объекта «2» не появилось, появилась другая рука.
Как из 5 фруктов выделить непосредственно
физическийреальный объект «5»? Но вообще хорошо, что тут вы сами двигаетесь в сторону абстракции. Если прибавить 2 грузовика к 3 стаканам сока, то 5 чего получится?Если взять пример с двумя руками — тут все очевидно, как были руки, так и остались, отдельного физического объекта 2 не появилось.
Если рассматривать пиксели на экране или звуковые волны или что угодно вы там используете для описания числа 2, то это тоже не работает вот почему: Если сложить число 2 с числом 3 — должно получиться число 5, а у вас получится какая-то мешанина пикселей или звуковых колебаний.
Следуя вашей логике слово — это тоже реальный объект, потому что в той или иной форме он существует у всех народов?
Больше того скажу, в Полинезии существуют народы, которые не знают данной абстракции. У них натурально для каждого существительного есть отдельные слова для разного количества. То есть отдельное слово для одной овцы, отдельное слово для двух овец. Аналогично с деревьями. И они не находят общих признаков у двух овец и двух деревьев.