Ответ 1
Нет, threading=multi
не означает, что такие вещи, как форсированные контейнеры, внезапно станут безопасными для одновременного доступа несколькими потоками (что было бы чрезмерно дорогостоящим с точки зрения производительности).
Скорее, теоретически это означает, что boost будет скомпилирован для понимания потоков. В основном это означает, что методы и классы boost будут вести себя разумным образом по умолчанию при доступе к нескольким потокам, подобно классам в std-библиотеке. Это означает, что вы не можете получить доступ к одному и тому же объекту из нескольких потоков, если не оговорено иное, но вы можете безопасно обращаться к различным объектам из нескольких потоков. Это может показаться очевидным даже без явной поддержки, но любое состояние static
, используемое библиотекой, нарушит эту гарантию, если не будет защищена. Использование threading=multi
гарантирует, что любое такое разделенное состояние является свойством, защищенным мьютеком или каким-либо другим механизмом.
В прошлом аналогичные аргументы или stdlib были доступны для библиотек C и С++ std, поставляемых с моими компиляторами, хотя сегодня в основном доступны только многопоточные версии.
Вероятно, существует небольшой недостаток в компиляции с threading=multi
, учитывая, что необходимо синхронизировать только ограниченное количество статического состояния. Ваш комментарий о том, что ваша библиотека будет в основном вызвана только одним потоком, не внушает большой уверенности - в конце концов, это те скрытые ошибки, которые заставят вас проснуться в 3 часа утра вашим боссом после ночи длительного питья.
Пример boost shared_ptr
информативен. При threading=single
даже не гарантируется, что независимая манипуляция двумя экземплярами shared_ptr
из нескольких потоков безопасна. Если они указывают на один и тот же объект (или, теоретически, при некоторых экзотических реализациях, даже если они этого не делают), вы будете генерировать поведение gen undefined, потому что совместное состояние не будет обрабатываться с надлежащей защитой.
С threading=multi
этого не произойдет. Тем не менее, он все еще небезопасен для доступа к тому же экземпляру shared_ptr
из нескольких потоков. То есть, он не дает никаких гарантий безопасности потоков, которые не документированы для рассматриваемого объекта, но это дает гарантии "ожидаемые/разумные/дефолтные" независимые независимые объекты. Не существует хорошего названия для этого уровня безопасности потоков, который по умолчанию является стандартным, но на самом деле это то, что в целом предлагает все стандартные библиотеки для многопоточных языков сегодня.
В качестве конечной точки стоит отметить, что Boost.Thread
неявно всегда компилируется с помощью threading=multi
- поскольку использование многопоточных классов boost является неявным намеком на то, что присутствуют несколько потоков. Использование Boost.Thread
без многопоточной поддержки было бы бессмысленным.
Теперь, все сказанное выше, теоретическая идея компиляции boost "с поддержкой потоков" или "без поддержки потоков", которая является целью флага threading=
. На практике, поскольку этот флаг был введен, многопоточность стала стандартной, и однопоточное исключение. Действительно, многие компиляторы и компоновщики, которые по умолчанию не выполняли однопоточное поведение, теперь по умолчанию используют многопоточность - или, по крайней мере, требуют только одного "подсказки" (например, наличия -pthread в командной строке) для переключения на многопоточность.
Кроме того, были предприняты согласованные усилия, чтобы сделать сборку "умных" - тем, что она должна переходить в многопоточный режим, когда окружающая среда его поддерживает. Это довольно расплывчато, но обязательно так. Это становится настолько сложным, как слабая связь символов pthreads, так что решение использовать MT или ST-код фактически отложено на время выполнения - если pthreads доступно во время выполнения, эти символы будут использоваться, иначе слабосвязанные заглушки - которые ничего не делают на всех - будет использоваться.
Суть в том, что threading=multi
является правильным и безопасным для вашего сценария, и особенно если вы создаете двоичный файл, вы будете распространять его на другие хосты. Если вы этого не сделаете, очень вероятно, что он будет работать в любом случае из-за эвристики времени сборки и даже эвристики времени исполнения, но вы используете возможность тихо использовать пустые методы заглушки или иным образом использовать MT-небезопасный код. Существует немного недостатка в использовании правильного варианта, но некоторые детали gory также можно найти в комментариях к этому моменту, и Игорь ответил также.