Когда на тысячи я использую хак (а может так и надо?) в виде пула, но я полностью за Ваш вариант с async-await по сравнению с примером выше с reduce, если нужно именно последовательно.
Это к чему? Тут как раз, скорее всего, async-await не нужен, потому что, скорее всего, нет смысла обрабатывать URL'ы по очереди, было бы лучше «одновременно».
Я совсем не эксперт в функциональном программировании и в async-await в JS, но, на мой взгляд, пример в статье совсем не отражает её суть.
В частности, практически каждый метод имеет побочные эффекты, любой метод может изменить внутреннее состояние аргумента, и, в общем-то, часто именно эти явления и ожидаются. То есть, идеологически полный провал.
Кстати, `isUserValidAsync` было бы лучше назвать assertValidUserAsync или использовать по-другому.
С другой стороны, в случае использования async-await, на мой взгляд, существенно улучшается читабельность кода от чего напрямую зависит его качество и стоимость поддержки. Хотелось бы заметить, что читабельность улучшается за счет меньшего количества всяких скобочек, запятых, вызываемых методов и вообще меньше кода.
При этом никто не запрещает использовать элементы функционального подхода, только без лишних ограничений на способ выражения желаемого. К тому же, наверняка, JS-движок следующей версии сможет существенно оптимальнее представить внутри себя async-await конструкции, чем свалку promise'ов, а программист все так же может продолжать использовать более менее простую модель с выворачиванием этого всего в promise'ы.
Понятно, для телефона можно узнать по крайней мере теоретически поддерживаемые конфигурации, а как узнать, что предоставляет оператор в конкретном районе? Нет ли каких-либо открытых карт с этой информацией и дальнейшими планами и, желательно, не только для России?
Тут та же самая ошибка, если один из потоков использует неконстантные методы доступа, то будет data race.
All member functions (including copy constructor and copy assignment) can be called by multiple threads on different instances of shared_ptr without additional synchronization even if these instances are copies and share ownership of the same object. If multiple threads of execution access the same shared_ptr without synchronization and any of those accesses uses a non-const member function of shared_ptr then a data race will occur; the shared_ptr overloads of atomic functions can be used to prevent the data race.
Как передать в другой тред? — использовать другие неблокирующие структуры данных, например, попробовать неблокирующие очереди, но это пахнет тем же мьютексом на спин-локах. Хотя производительность надо мерить в конкретном случае.
При любых операциях с собственно указателем, например присвоении, мы должны атомарно проверять счетчик и одновременно изменять указатель на контрольный блок, что невозможно используя существующие атомарные примитивы.
Похоже, что так, если только кто-нибудь не придумает какой-нибудь трюк вроде tagged pointer, еще одного уровня вложенности или еще чего.
На самом деле я был бы рад ошибиться, возможно есть что-то, что я не знаю или понимаю неправильно?
А не посмотрите реализацию std::experimental::atomic_shared_ptr?
Пусть в разделяемой памяти находится некоторая информация упакованная в структуру и доступная через указатель. Есть один или множество независимых потоков, которые должны читать и использовать эти данные без модификации, как правило оказывается что для них критически важна скорость доступа. В то же время, пусть существует один или несколько потоков модифицирующих эти данные с нарушением целостности, на практике обычно оказывается что модификации случаются значительно реже и скорость доступа там не настолько важна.
…
Однако же я, прослышав что std::shared_ptr дает потокобезопасный доступ к контрольному блоку (и не очень понимая что это значит), а так же что операции над ним реализованы lock-free, хочу предложить свое изящное решение:
далее идет пример, того как делать не надо, а, как сказали выше, надо было просто дальше прочитать документацию. Хорошо, но как решить задачу без дополнительных финтов с блокировками?
Заметим, что читающий поток может пропустить часть данных, тогда это можно сделать, используя weak_ptr (считаем, что писатели могут синхронизироваться отдельно, тут задержка не важна). При этом, я считаю, что существует неблокирующий способ передачи этого самого weak_ptr в читающий поток.
Если же смотреть только на код примера, то то можно подумать, что речь идёт о том, что читающий поток живет все время и только и делает, что пытается прочитать данные, которые обновляются, но нечасто, и при этом все равно может пропустить часть данных. На мой взгляд тут проблема поважнее, и она не в деталях чтения памяти, а в подходе в целом. Это либо неэффективно, либо читающий поток захлебнется.
Исходный sp удаляется сразу после std::thread::detach, потому что «заканчивается scope», при этом в другом потоке мы пытаемся получить к нему доступ через std::weak_ptr.
Как ответили выше, это в общем-то и в документации есть. То, что Вы хотите можно сделать при помощи std::weak_ptr. std::weak_ptr::lock должна быть атомарна.
Псевдо-код:
int main() {
uint32_t i = 10000;
while (i-- > 0) {
auto sp = std::make_shared<int>();
std::weak_ptr p = sp;
thread([p]{
if (auto sp = p.lock()) {
// pointer is valid, Cool, use sp
} else {
// pointer is already expired, ignore
}
}).detach();
}
return 0;
}
Во-первых, напомнило python, где тут же налетят и предложат десять способов написать правильный for, да еще и для разных версий.
По статье:
Все таки типовой код скорее всего работает с полями объектов или, по крайней мере, структур, аллоцирует большое количество новых объектов, частенько обращается к уже выгруженным страницам памяти и так далее. Так что навряд ли вы встретите сортировку чисел пузырьком в большинстве программ.
Это хорошо, что Вы тестируете на одних и тех же данных, но в чем смысл сортировать уже отсортированный массив?
Да и вообще, производительность числодробильного кода и там и там должна быть примерно одинаковая, основной источних тормозов — неучтенная работа с чем-то медленным, потом работа с памятью, и с большим отставанием идет кривая архитектура.
В программах C++ все же довольно часто прибегают к тем или иным способам оптимизации. И там и там сначала профилирование, анализ данных, а потом оптимизация.
Стрелка в Кёльне, ни разу не видел в действии, фото тоже найти не могу. Идея в том, что вагон заезжает, рельсы поворачиваются на другой путь и вагон выезжает.
Круто, я тоже пользовался fiddler'ом, но хотел немного более интеллектуального бота. Поделюсь своей наработкой немного деобфусцированного скипта, правда, одной из предыдущих версий, gist.github.com/abby-sergz/65aad7682de388f14ee2.
В частности, практически каждый метод имеет побочные эффекты, любой метод может изменить внутреннее состояние аргумента, и, в общем-то, часто именно эти явления и ожидаются. То есть, идеологически полный провал.
Кстати, `isUserValidAsync` было бы лучше назвать assertValidUserAsync или использовать по-другому.
С другой стороны, в случае использования async-await, на мой взгляд, существенно улучшается читабельность кода от чего напрямую зависит его качество и стоимость поддержки. Хотелось бы заметить, что читабельность улучшается за счет меньшего количества всяких скобочек, запятых, вызываемых методов и вообще меньше кода.
При этом никто не запрещает использовать элементы функционального подхода, только без лишних ограничений на способ выражения желаемого. К тому же, наверняка, JS-движок следующей версии сможет существенно оптимальнее представить внутри себя async-await конструкции, чем свалку promise'ов, а программист все так же может продолжать использовать более менее простую модель с выворачиванием этого всего в promise'ы.
http://wiki.yobi.be/wiki/Forensics_on_Incident_3
boostcon/cppnow 2016/implementing_a_lock_free_atomic_shared_ptr.pdf
И там дальше по ссылке литературы www.1024cores.net differential-reference-counting
http://en.cppreference.com/w/cpp/memory/shared_ptr
Как передать в другой тред? — использовать другие неблокирующие структуры данных, например, попробовать неблокирующие очереди, но это пахнет тем же мьютексом на спин-локах. Хотя производительность надо мерить в конкретном случае.
Похоже, что так, если только кто-нибудь не придумает какой-нибудь трюк вроде tagged pointer, еще одного уровня вложенности или еще чего.
А не посмотрите реализацию std::experimental::atomic_shared_ptr?
далее идет пример, того как делать не надо, а, как сказали выше, надо было просто дальше прочитать документацию. Хорошо, но как решить задачу без дополнительных финтов с блокировками?
Заметим, что читающий поток может пропустить часть данных, тогда это можно сделать, используя weak_ptr (считаем, что писатели могут синхронизироваться отдельно, тут задержка не важна). При этом, я считаю, что существует неблокирующий способ передачи этого самого weak_ptr в читающий поток.
Если же смотреть только на код примера, то то можно подумать, что речь идёт о том, что читающий поток живет все время и только и делает, что пытается прочитать данные, которые обновляются, но нечасто, и при этом все равно может пропустить часть данных. На мой взгляд тут проблема поважнее, и она не в деталях чтения памяти, а в подходе в целом. Это либо неэффективно, либо читающий поток захлебнется.
Псевдо-код:
По статье: