Здравствуйте, Kolobrodin, Вы писали:
K>С таким же успехом можно было заюзать:
K>static InstanceTypeRef getInstance() K>{ K> static InstanceType s_instance; K> return s_instance; K>}
K>И надо сказать, это кое-где работает
простите, что немного офтоп, но нельзя ли пояснить, что тут не так? На практике проблем не было (гцц), и я так понимаю гцц это дело поддерживает, но может какие-то там ещё проблемы глубже, очень хотелось бы понять.
Здравствуйте, brankovic, Вы писали:
B>простите, что немного офтоп, но нельзя ли пояснить, что тут не так? На практике проблем не было (гцц), и я так понимаю гцц это дело поддерживает, но может какие-то там ещё проблемы глубже, очень хотелось бы понять.
Но обычно хотят singleton близкий по описанию к singleton с двумя проверками, чтобы под другими компиляторами (MSVC) тоже работало. Ну, и соответственно, пиплы, программирующие исключительно под MSVC, на собеседованиях относятся к варианту от gcc крайне скептически и готовы прямо в митингруме расжечь костер и наказать еретика. Несмотря на то, что старательно объясняешь разницу, они не могут поверить, что компилятор может следить... Доставляет, однако.
Неоконченная мысль всегда казалась Шри Япутре слишком
K>Но обычно хотят singleton близкий по описанию к singleton с двумя проверками, чтобы под другими компиляторами (MSVC) тоже работало. Ну, и соответственно, пиплы, программирующие исключительно под MSVC, на собеседованиях относятся к варианту от gcc крайне скептически и готовы прямо в митингруме расжечь костер и наказать еретика. Несмотря на то, что старательно объясняешь разницу, они не могут поверить, что компилятор может следить... Доставляет, однако.
Ни в коем случае не стоит рассматривать фразу как приглашение к холивару, но как предостережение от холивара
Неоконченная мысль всегда казалась Шри Япутре слишком
Re[12]: Как защитить mutex singletona
От:
Аноним
Дата:
10.04.11 17:06
Оценка:
Здравствуйте, Kolobrodin, Вы писали:
K>Может здесь или здесь?
конкуренция со спином хорошо конечно, но надо же конкурировать за ИНИЦИАЛИЗИРОВАННЫЙ объект, тоесть создать статик синхронизатор, а потом его лочить. И тем самым возвращаемся к проблеме лока во время инициализации статики Или я чего не понял ? Можно создать шаблоный статик для класса и после входа в main можно гарантировано лочится им в любых классах. Но это не то, это другие задачи решает, уже просто синхронизацию, а тут основная трабла защитится от дыр при построение глобальной статики. Даже если мы втыкиваем инициалиацию этого синхронизатора через шварца, то в самом шварце защиты тоже нету.
О, gcc поддерживает thread-safe инициализацию, вот блин молодцы.
PS >Надо чаще на старый код смотреть. Зачем-то static в namespace засунул
Красоту наводишь ? каждая переменная имеет linkage spec, по умолчанию static, все равно что signed перед int написать
Здравствуйте, andrey.desman, Вы писали:
AD>Здравствуйте, Kolobrodin, Вы писали:
K>>Надо чаще на старый код смотреть. Зачем-то static в namespace засунул
AD>Раз уж на то пошло, то можно еще и spinlock_data выровнять.
Спасибо А как это лучше сделать инновационным способом?
ЗЫ. Как там в Индусии?
Неоконченная мысль всегда казалась Шри Япутре слишком
Здравствуйте, Kolobrodin, Вы писали:
AD>>Раз уж на то пошло, то можно еще и spinlock_data выровнять. K>Спасибо А как это лучше сделать инновационным способом?
struct sdata
{
int dummy;
char data[sizeof(spinlock)];
} spinlock_data;
Но здесь теоритических гарантий на выравнивание нет, хотя на практике ни один из компиляторов не будет мусорить дырками между dummy и data.
Как-то сталкивался с такой проблемой, когда портировал код на более старый армовский компилятор. Там std::wstring вылетал в конструкторе по умолчанию из-за невыровненных данных. Да, там тоже выделяли память статик чаром под единый инстанс пустой строки Задолбался я тогда ковыряться в недрах того STL, продираясь сквозь все эти жутко нечитаемые шаблоны в шаблонах и #ifdef.
K>ЗЫ. Как там в Индусии?
Дурдом там Пришел к выводу, что все это нужно только чтобы увидеть красивую картинку перед смертью
Здравствуйте, andrey.desman, Вы писали:
AD>Здравствуйте, Kolobrodin, Вы писали:
AD>>>Раз уж на то пошло, то можно еще и spinlock_data выровнять. K>>Спасибо А как это лучше сделать инновационным способом?
AD>А х.з. AD>Можно так: AD>
AD>Но здесь теоритических гарантий на выравнивание нет, хотя на практике ни один из компиляторов не будет мусорить дырками между dummy и data.
AD>Как-то сталкивался с такой проблемой, когда портировал код на более старый армовский компилятор. Там std::wstring вылетал в конструкторе по умолчанию из-за невыровненных данных. Да, там тоже выделяли память статик чаром под единый инстанс пустой строки Задолбался я тогда ковыряться в недрах того STL, продираясь сквозь все эти жутко нечитаемые шаблоны в шаблонах и #ifdef.
std::aligned_storage в <type_traits> есть. Это из нового С++0х.
Объявлено так:
template<std::size_t _Len, std::size_t _Align>
struct aligned_storage
{
union type
{
unsigned char __data[_Len];
struct __attribute__((__aligned__((_Align)))) { } __align;
};
};
Предположение, что данные, кратные по размеру некоторому X, компилятор пытается разместить по кратному X адресу? Иначе смысла не вижу.
K>>ЗЫ. Как там в Индусии? AD>Дурдом там Пришел к выводу, что все это нужно только чтобы увидеть красивую картинку перед смертью
Неоконченная мысль всегда казалась Шри Япутре слишком
Здравствуйте, Kolobrodin, Вы писали:
K>Предположение, что данные, кратные по размеру некоторому X, компилятор пытается разместить по кратному X адресу? Иначе смысла не вижу.
Пытается? Нечеткая логика, ха.
У разных базовых типов разное выравнивание на разных платформах и даже компиляторах. И компилятор обязан это выравнивание соблюсти, если не сказано иначе (типа packed, __align__ и т.д.).
Смысл в том, чтобы использовать тип с максимальным выравниванием, тогда любые данные по этому адресу будут выровнены.
Максимальное выравнивание, которое мне известно, имеет long double на 64-битном линуксе (16 байт), так что тут int ничего не решает, если внутри spinlock есть long double
Здравствуйте, andrey.desman, Вы писали:
AD>Смысл в том, чтобы использовать тип с максимальным выравниванием, тогда любые данные по этому адресу будут выровнены.
Я вот это не догнал Выравнивание размера или выравнивание адреса и как оно взаимосвязано?
Неоконченная мысль всегда казалась Шри Япутре слишком
Здравствуйте, Kolobrodin, Вы писали:
K>Здравствуйте, andrey.desman, Вы писали:
AD>>Смысл в том, чтобы использовать тип с максимальным выравниванием, тогда любые данные по этому адресу будут выровнены.
K>Я вот это не догнал Выравнивание размера или выравнивание адреса и как оно взаимосвязано?
Для базовых типов выравнивается адрес. Размер дополняется, чтобы этот тип в массиве сохранял свое выравнивание. Например, это делается для long double, который имеет реальный размер 10 байт, но на 32 битах требует выравнивания на 4 байта. Соответственно, его размер добивается до 12 байт, а на 64 битах требует выравнивания 16 байт и размер его дополняется до 16 байт.
Соответственно, выравнивание структуры — это максимальное выравнивание члена этой структуры (рекурсивно и для подструктур/юнионов), и размер структуры дополняется для того, чтобы в массиве выравнивание для каждого члена сохранялось.
Вот кстати, вариант с юнионом наверное лучший long double заставляет компилятор выровнять aligned_data по максимуму.
union sp
{
char spinlock_data[sizeof(spinlock)];
long double align;
} aligned_data;
Здравствуйте, andrey.desman, Вы писали:
AD>Здравствуйте, Kolobrodin, Вы писали:
K>>Здравствуйте, andrey.desman, Вы писали:
AD>>>Смысл в том, чтобы использовать тип с максимальным выравниванием, тогда любые данные по этому адресу будут выровнены.
K>>Я вот это не догнал Выравнивание размера или выравнивание адреса и как оно взаимосвязано?
AD>Для базовых типов выравнивается адрес. Размер дополняется, чтобы этот тип в массиве сохранял свое выравнивание. Например, это делается для long double, который имеет реальный размер 10 байт, но на 32 битах требует выравнивания на 4 байта. Соответственно, его размер добивается до 12 байт, а на 64 битах требует выравнивания 16 байт и размер его дополняется до 16 байт. AD>Соответственно, выравнивание структуры — это максимальное выравнивание члена этой структуры (рекурсивно и для подструктур/юнионов), и размер структуры дополняется для того, чтобы в массиве выравнивание для каждого члена сохранялось.
AD>Вот кстати, вариант с юнионом наверное лучший long double заставляет компилятор выровнять aligned_data по максимуму.
AD>
Здравствуйте, andrey.desman, Вы писали:
AD>Это как минимум три разных операции (если смотреть не самый низкий уровень): выделение памяти, вызов конструкторов, запись в переменную. Последние два компилятор/процессор может распараллелить или поменять местами.
1. std::string* str = new std::string("abc");
2. str->data();
что в точке 2 str будет указывать на какой-то объект класса std::string, который ещё не сконструирован строкой "abc" из-за переупорядочивания инструкций компилятором/процессором
Здравствуйте, баг, Вы писали:
баг>Не верю.
Счастливой отладки!
баг>Это всё равно, что сказать баг>
1. std::string* str = new std::string("abc");
баг>2. str->data();
баг>
баг>что в точке 2 str будет указывать на какой-то объект класса std::string, который ещё не сконструирован строкой "abc" из-за переупорядочивания инструкций компилятором/процессором
Не все равно. Здесь очевидная для компилятора зависимость (2) от (1), а там этой зависимости нет, потому что о потоках компилятор ничего не знает. Вообще не все так просто, как кажется на первый взгляд. Ссылку здесь уже приводили, почитай, много интересного узнаешь http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
Re[5]: Как защитить mutex singletona
От:
Аноним
Дата:
13.04.11 17:07
Оценка:
Здравствуйте, баг, Вы писали:
баг>Здравствуйте, andrey.desman, Вы писали:
AD>>Это как минимум три разных операции (если смотреть не самый низкий уровень): выделение памяти, вызов конструкторов, запись в переменную. Последние два компилятор/процессор может распараллелить или поменять местами.
баг> Вы хотите сказать, что
баг>
мутекс статический! соответсвенно первый поток может войти и инициировать его конструктор, а второй, зайдя будет подразумевать, что мутекс создан, и в точке захвата будет undefined behavior, если первый не успеет его инициализировать. Если вам это интересно, то в другой(более длинной) ветке обсуждение этой фичи.