Threads и fork: дважды подумайте
Да, дважды подумайте перед тем как смешивать их: http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them
Да, дважды подумайте перед тем как смешивать их: http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them
Если коротко, то всё, что связано с std::locale
в MinGW не работает. Точка.
Зато вполне себе работает функционал из Си:
std::locale::global(std::locale("")); // не установит текущую локаль
setlocale(LC_ALL, ""); // установит текущую локаль, у меня это Russian_Russia.Cp1251
Статью изначально публиковал на хабре: http://habrahabr.ru/post/232775/. Здесь - для единства мыслей :)
Когда не так часто, как хотелось бы, приходится работать с языком, некоторые аспекты забываются. А некоторые никогда и не откладываются в голове. Поэтому, когда возникают вопросы, приходится отвлекаться и лезть в документацию.
Чтобы сэкономить время в последующем, а также, чтобы лучше понять в ходе обучения, крайне помогает вести конспекты и делать наглядные шпаргалки. Шпаргалку можно повесить рядом на стену. Хороши шпаргалки в виде блок-схем, по которым можно легко, по шагам, получить нужный результат (например выбрать правильный контейнер).
Под катом я решил опубликовать пару шпаргалок для определения условия когда будет создан компилятором неявно-генерируемый перемещающий конструктор и перемещающий оператор присваивания.
Шпаргалки представлены в виде PDF файлов для печати на принтере A4, в виде картинки PNG, а также исходников в SVG.
Однажды писал про двоичные литералы в GCC: /post/2009-10-02_13.44_0b00100100, новый стандарт C++14 закрепил их в C++.
Но тут я хотел бы рассмотреть лёгкий способ перехода в уме между hex и bin представлениями.
Стандарт отправился в печать: https://isocpp.org/blog/2014/08/we-have-cpp14
Сильно быстро меняется, компиляторы не поспевают, не то что головы программистов и промышленность. Надеюсь они притормозят коней, да займутся больше багофиксами.
Удобный сервис для анализа последовательностей и поиска зависимостей и вывода формулы: http://oeis.org/
Удобно использовать для различных видов анализа, обратной разработки и т.п.
Условное удаление по значению из всяких там map и иже с ними. А так же, бонусом, наиболее оптимальный вариант условного удаления для вектора.
Ничего нового, просто ссылки:
Если коротко, то что даёт применение ключевого слова const
везде, где это уместно:
<WRAP center round tip 60%>
Побитовая константность - когда при вызове ни один бит структуры или класса не меняется.
Логическая константность - когда при вызове какие-то поля могут меняться, но данные, отвечающие за логику класса не изменяются.
Обычно последнее связано с полями, которые имеют спецификатор mutable
. Для чего они нужны? Самый простой пример: экземпляр класса может использоваться из разных потоков. Писать может один поток, а читать другой. Логично, что метод для чтения будет константным. Так же логично, что чтение и запись следует защитить мьютексом. Но если мы попробуем заблокировать мьютекс в константном методе, получис ошибку компиляции. Понятно, что изменение мьютекса никак не влияет на логическую константность класса, поэтому его можно объявить mutable
и спокойно защищать им данные.
Из примера выше можно сделать такое неформальное заключение: <WRAP center round tip 60%> Побитовая константностью - неиболее сильная. Логическая - более слабая.
Небольшая заметка о том, как форсировать поддержку C++11 в парсере для различных билд-систем. Заметки касаются master-снапшота QTC (брать тут: http://download.qt-project.org/snapshots/qtcreator/master/latest/ или собирать из исходников).
Нужно отметить, что синтаксис нового стандарта поддерживается сейчас по-умолчанию. Проблемы касаются правильного определения констант компилятора, подключения частей стандартной библиотеки и т.п.
С приходом нового стандарта эти две свободные функции появились в STL, в библиотеке итераторов (#include <iterator>
). Кроме того, в примерах кода часто можно увидеть, что они используются на STL контейнерах вместо собственных методов .begin()
и .end()
:
#include <iostream>
#include <vector>
#include <iterators>
using namespace std;
int main()
{
vector<int> v{1, 2, 3, 4, 5};
for (auto it = begin(v); it != end(v); ++it)
{
cout << "Number: " << *it << endl;
}
return 0;
}
Мне хорошо понятно, что эти функции отлично подходят для RAW-массивов, т.е. если в примере выше заменить:
vector<int> v{1, 2, 3, 4, 5};
на
int v[] = {1, 2, 3, 4, 5};
или даже
int v[]{1, 2, 3, 4, 5};
То весь остальной код менять не нужно. Удобно, причём мы защищены от подсовывания указателя вместо массива. Но почему они применяются для STL контейнеров?
Поиск по интернету дал только один ответ: для унификации. И только.
Т.е. ни по “кошерности” ни по скорости два этих подхода не отличаются. Чисто для единства вида.
Если у кого есть другие предположения - милости просим в дискуссию.
Ссылки
Дошли руки до включения данной фичи на моём ноутбуке. Всё оказалось не просто, а очень просто, в случае Linux Mint 16, всё делаем по инструкции: http://help.ubuntu.ru/wiki/bumblebee для Linux Mint 16 смотрим на версии убунты 13.10, для будущего Linux Mint 17 - 14.04.
За более детальными настройками: https://wiki.archlinux.org/index.php/Bumblebee_%28%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9%29
Если коротко:
lspci -nn | grep VGA
наблюдаем две строки, а не одну, как обычно.sudo apt-get install nvidia-319-updates nvidia-settings-319-updates
sudo apt-get install bumblebee bumblebee-nvidia primus primus-libs-ia32
После загрузки смотрим вывод optirun --status
видим, что всё ок. А приложения запускаем:
optirun [аргументы] <приложение> [аргументы приложения]
Для самых нетерпеливых, можно сравнить вывод двух команд: glxinfo optirun glxinfo
Если при старте вылазит такое:
...using GL_NV_blend_square
...using GL_ARB_texture_compression
X..GL_EXT_texture_compression_s3tc not found
Fatal Error: Texture compression unavailable
Shutting down SDL subsystem
--------------- BSE Shutdown ----------------
---------------------------------------------
idRenderSystem::Shutdown()
Sys_Error: Texture compression unavailable
Нужно сделать следующее:
driconf
, для deb-based: apt-get install driconf
Всё, радуемся игре.
Часто вижу непонимание того, как и почему должен работать газ на холоде. Была задумка скомпоновать всю полученную информацию воедино, но так сложилось, что все уже сделано за нас. Итак, подборка:
Дома дополню про вес баллонов, в т.ч. для “экспедиционных” 5 и 12л пропановых.
Но если кратко:
Отсюда видно, что чем в смеси больше пропана и меньше бутана, тем газ лучше будет работать в холодную погоду. Наиболее оптимальными на холода будут пропан-изобутановые смеси, где не меньше 20-25% пропана.
Чисто пропановые баллоны не делают по двум трём (на основании комментариев) причинам:
Т.е. теперь, глядя на баллон, хотя бы примерно можно представлять как он будет вести себя на холоде. По субъективным наблюдениям: “новая” ковеевская смесь (изобутан 72%, пропан 22%, бутан 6%) работает хорошо до -20 градусов. Будет больше пропана и меньше бутана - на меньшую температуру можно рассчитывать.
Ну и сразу же по расходу или сколько планировать газа на маршрут, взято отсюда: http://kovea.ru/articles/information/portativnye-gazovye-ballony-i-gazovye-kartridzhi/, но, в целом, отражает суть (хотя по оценка на высоте + топление снега как раз получалось около 160 грамм):
Количество газа нужно брать рассчитывается индивидуально исходя из условий, в которых будете находиться, при использовании газовых горелок и плит из-за сильного ветра теплопотери будут огромные, обязательно докупите ветрозащитный экран или сконструируйте сами. Обычно примерный расчет газа идет такой:
- 50 гр./чел в день – эконом..
- 80 гр./чел в день - оптимальный вариант
- 100 гр./чел в день – комфортные условия.
- 100-300 гр./чел в день – альпинизм (растопить снег, обычно берется в 2е больше примерно 160-200 гр./чел в день).
Интегрированные системы могут сэкономить расход газа на 20-30%.
Есть ещё варианты котлов под обычные горелки, но с радиатором. Судя по тестам, радиатор даёт выигрыш по времени около 40%, по расходу газа 15-20%.
Мои наблюдения и компоновка знаний по расходу газа в походах отражена в заметке: Расход газа в походе. Там же рекомендации, на какое количество газа ориентироваться под конкретную ситуацию.
И дополнительно по массе баллонов, начну с непривычных, бытовых баллонов (эти данные для ориентировки, на шильдике самого баллона более точная информация указана):
Программируя на Си многие сталкивались с такими функциями как memcpy()
и memmove()
, по сути, функции делают одно и тоже, но вторая корректно отрабатывает ситуацию, когда области памяти перекрываются (на что появляются дополнительные накладные расходы).
В мире С++ никто не запрещает пользоваться этими функциями (часто эти функции используют различные механизмы оптимизации и могут статься быстрее своих собратьев из мира C++), но есть и более родное средство, работающее через итераторы: std::copy
. Это средство применимо не только к POD типам, а к любым сущностям, поддерживающим итераторы. О деталях реализации в стандарте ничего не сказано, но можно предположить, что разработчики библиотеки не настолько глупы, что бы не использовать, оптимизированные memcpy()
/memmove()
когда это возможно.
Но по наитию, хочется посмотреть, а что там с пересекающимися областями (overlapping memory blocks)? Ведь задача, на самом деле, не такая уж редкая. К примеру, хотим мы читать MPEG-TS пакеты (размер каждого 188 байт, каждый пакет начинается с 0x47 /sync byte/) из какого-то потока, и есть вероятность, что первое (а может и последующее, либо имеем дело с M2TS контейнером, размер блока которого 192 байта и лишние 4 байта в большинстве случаем мы можем игнорировать) чтение может попасть на середину пакета. В таких случаях обычно делается так: вычитываем блок 188 байт, далее ищем байт синхронизации, если он в нулевой позиции - всё отлично, если нет, то данные от него и до конца, нужно переместить в начало блока, в освободившееся место нужно дочитать недостающу порцию, после чего пакет считается вычитанным и можно отдавать его на обработку.
Наглядно процесс копирования данных в начало блока можно показать этой картинкой:
Т.е. видим, что есть перекрытие. Логично, было бы применить какой-то аналог memmove()
, но в стандартной библиотеке есть только std::move
который делает совершенно не то. Но при этом, читая описание для std::copy
(
http://www.cplusplus.com/reference/algorithm/copy) видим следующую строчку:
The ranges shall not overlap in such a way that result points to an element in the range [first,last).
т.е. на самом деле, если начало области (result) куда копировать, лежит вне области [first,last), то всё должно быть ок. И это реально так.
Но посмотрим такую схему копирования с перекрытием:
пока не обращаем внимание на то, что result тут в конце. Смысл картинки в том, что блок памяти нужно сдвинуть с начала на какое-то смещение вперёд, соответственно если это смещение меньше размера сдвигаемого блока, то адрес назначения у нас будет лежать в пределах [first,last), таким образом условие применимости std::copy
не соблюдаются. И если применить его, мы просто затрём данным в перекрывающейся области.
Но тут на помощь нам приходит его собрат, как раз решающий эту проблему: std::copy_backward
, всё отличие этой функции в том, что он осуществляет копирование с конца. Т.е. для случая изображённой на второй картинке, он возьмёт (далее очень грубо, т.е. на самом деле last и result это указатели на конец блока, а ближайшие данные находятся по last-1 и result-1) элемент из last и ложится в result, далее из last-1 в result-1, далее из last-2 в result-2 и так далее.
Видно, что при такой схеме копирования, когда мы начнём писать в перекрывающуюся область, данные в ней уже будут обработаны. Т.е. для нас всё хорошо. Забавно, что условие применимости при перекрывающийся областях для std::copy_backward
слово в слово повторяет данное условие для std::copy
.
Итак, резюмируя, простое правило:
std::copy
, в качестве result указываем НАЧАЛО блока-назначения.std::copy_backward
, в качестве result указываем КОНЕЦ блока-назначения.Текст является творческим переосмыслением англоязычной статьи: http://www.trilithium.com/johan/2006/02/copy-confusion, картинки взяты от туда же, пример из собственного опыта.
Референс:
PS Статья была опубликована на Habrahabr: http://habrahabr.ru/post/218451
В синтаксисе регулярок в GCC 4.8.1/libstdc++4.8 нет поддержки квадратных скобок: []
. Пришлось использовать Boost.Regex
Ах да, пруф: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53631