2012-03-07 7 views
8

C++ 11 предлагает такие функции, как thread-safe initialization of static variables, и со ссылкой на этот вопрос, мы будем говорить, например:Предоставляются ли какие-либо гарантии безопасности потоков C++ 11 для сторонних библиотек потоков, скомпилированных/связанных с C++ 11?

Logger& g_logger() { 
    static Logger lg; 
    return lg; 
} 

Так якобы это справедливо независимо от того, является ли модуль скомпилирован с C++ 11 компилятора (?) включал заголовки нитей или порождал любые потоки в своем теле. Вам предлагается гарантия, даже если она была связана с другим модулем, который использовал потоки C++ 11 и вызвал функцию.

Но что, если ваш «другой модуль», который вызывает этот код, не использует потоки C++ 11, но что-то вроде Qt's QThread. Является ли атомная инициализация статики тогда вне сферы возможностей C++ 11 сделать такую ​​гарантию? Или сам факт того, что модуль, скомпилированный с C++ 11, а затем связанный с другим кодом C++ 11, подразумевает, что вы получите гарантию независимо?

Кто-нибудь знает хорошую ссылку, где покрыты такие проблемы?

+0

Статическая инициализация - свойство языка. Я не вижу, как это может повлиять на конкретную библиотеку. – pmr

+2

@pmr Мне кажется, что это немного сложно, потому что, например, память для вышеуказанного статического выделяется в начале программы, но конструктор запускается при первом вызове функции со статикой внутри нее. Казалось бы, для того, чтобы добиться этого, требуется всеведение в отношении модели потока нитей, поэтому я скептически отношусь к этому, если бы смешал QThread/C++ 11thread ... хотя есть небольшая вероятность появления новых бинарных требований, которые заставляют его работать , – HostileFork

+0

@HostileFork: Пока оба (C++ и qt) используют одни и те же средства ОС для потоковой передачи, я не вижу, как что-то может пойти не так. Также я не понимаю, почему ни один из них не должен использовать средства потоковой передачи ОС. – PlasmaHH

ответ

4

Ваш пример основан на модели памяти, а не на том, как реализованы потоки. Тот, кто выполнит этот код, выполнит те же инструкции. Если два или более ядра выполняют этот код, они будут подчиняться модели памяти.

Основная реализация эквивалентна следующему:

std::mutex mtx; 
Logger * lg = 0; 
Logger& g_logger() { 
    std::unique_lock<std::mutex> lck(mtx); 
    if (lg == 0) 
     lg = new Logger; 
    return *lg; 
} 

Этот код может быть оптимизирован для использования с двойной проверкой блокировкой шаблона (DCLP), который, на архитектуре частности, процессора (например, на x86) может быть намного быстрее. Кроме того, поскольку компилятор генерирует этот код, он будет знать, что он не делает безумных оптимизаций, которые нарушают наивный DCLP.

+0

Прохладный, спасибо ... похоже, есть консенсус, что это * предполагается * быть безопасным. FYI: Причина, по которой я рассматривал этот вопрос, заключалась в том, чтобы решить этот сценарий ... http://stackoverflow.com/questions/9507973/how-to-mitigate-user-facing-api-eectect-of-shared-members-in -templated-классы – HostileFork

7

Кто-нибудь знает хорошую ссылку, где такие проблемы покрыты?

Несомненно. Стандарт C++. Он описывает поведение кода на C++. Если ваша библиотека - это код на C++, необходимо следовать этому поведению. Так что да, вы получаете те же гарантии, что и ваш собственный код.

Точно, как компилятор/время работы/ОС/все остальное снимает его - это не ваша проблема. Стандарт C++ гарантирует, что он позаботился.

+0

Точка взята. Однако независимо от того, является ли это моей проблемой или нет, я хотел бы знать, использую ли я GCC и Qt, если они сделали магию, чтобы «снять ее». С технической точки зрения, если C++ 03 'static.a' были связаны с исполняемым файлом C++ 11 'icallthestatic', маловероятным, что компоновщик сможет это сделать. Но это указывает на более широкую проблему «вы, вероятно, не можете связать код C++ 03 с C++ 11 и получить гарантии C++ 11 для системы» ... – HostileFork

+0

Код C++ 03 гарантированно только ведет себя как C++ 03. Поэтому, если вы ссылаетесь на библиотеку C++ 03, вы не можете рассчитывать на нее, предоставляя гарантии, предоставляемые только C++. 11 – jalf