class A
{
long m_a;
public:
long get_a()
{
return m_a;
}
void set_a( long val )
{
m_a = val;
}
}
методы get_a и set_a вызываются из разных потоков.
вопрос:
может ли быть, что доступ к этой переменной будет во время ее записи и, например, вернется не ее предыдущее(или новое) значение, а что то вроде:
старшие 2 байта будут от нового значения, а младшие 2 байта будут от старого?
Здравствуйте, sidorov18, Вы писали:
S>вопрос: S>может ли быть, что доступ к этой переменной будет во время ее записи и, например, вернется не ее предыдущее(или новое) значение, а что то вроде: S>старшие 2 байта будут от нового значения, а младшие 2 байта будут от старого?
может
Re[2]: вопрос по синхронизации в многопоточной среде
Интересно как, ведь операции процессора являются дискретными, а в данном случае я полагаю
используется 32-битный код, следовательно чтение или запись производится одной
операцией и следовательно половинное значение получить невозможно.
Здравствуйте, sidorov18, Вы писали:
S>вопрос: S>может ли быть, что доступ к этой переменной будет во время ее записи и, например, вернется не ее предыдущее(или новое) значение, а что то вроде: S>старшие 2 байта будут от нового значения, а младшие 2 байта будут от старого?
Процессор какой?
bloß it hudla
Re[3]: вопрос по синхронизации в многопоточной среде
Здравствуйте, tripol, Вы писали:
T>Здравствуйте, uzhas, Вы писали:
U>>может
T>Интересно как, ведь операции процессора являются дискретными, а в данном случае я полагаю T>используется 32-битный код, следовательно чтение или запись производится одной T>операцией и следовательно половинное значение получить невозможно.
Ну, во-первых, 32хбитный код не обязательно подразумевает 32хразрядную шину данных. Во-вторых, чтение и запись запросто могут быть не в память, а в кеш. И тут вообще может случиться много забавного. Например, первые два байта в одной строке, остальные — в другой.
Здравствуйте, sidorov18, Вы писали:
S>может ли быть, что доступ к этой переменной будет во время ее записи и, например, вернется не ее предыдущее(или новое) значение
а что в данном случае не воспользоваться interlocked функциями?
Re[4]: вопрос по синхронизации в многопоточной среде
Здравствуйте, _stun_, Вы писали:
__>Ну, во-первых, 32хбитный код не обязательно подразумевает 32хразрядную шину данных. Во-вторых, чтение и запись запросто могут быть не в память, а в кеш. И тут вообще может случиться много забавного. Например, первые два байта в одной строке, остальные — в другой.
Для программы кэш должен быть прозрачным, иначе тогда много геморою...
Re[5]: вопрос по синхронизации в многопоточной среде
Здравствуйте, _stun_, Вы писали:
__>Здравствуйте, tripol, Вы писали:
T>>Для программы кэш должен быть прозрачным, иначе тогда много геморою...
__>Должен — это когда взял, и не отдал Разговор идет про то, что есть, а не про то, что могло бы быть.
Если в системе есть подобные неоднозначности — то тут тогда необходимо выполнять синхронизацию
кэшей программно. Но хорошо, что разработчики систем от этого гемороя програмистов берегут.
Смотрите: MSEI Protocol
Банально все сводится к использованию CriticalSection или Mutex-ов без каких-либо забот
об кэшах.
Re[7]: вопрос по синхронизации в многопоточной среде
Здравствуйте, sidorov18, Вы писали:
S>есть класс: S>
S>class A
S>{
S> long m_a;
S>public:
S> long get_a()
S> {
S> return m_a;
S> }
S> void set_a( long val )
S> {
S> m_a = val;
S> }
S>}
S>
S>методы get_a и set_a вызываются из разных потоков.
S>вопрос: S>может ли быть, что доступ к этой переменной будет во время ее записи и, например, вернется не ее предыдущее(или новое) значение, а что то вроде: S>старшие 2 байта будут от нового значения, а младшие 2 байта будут от старого?
Такое может случиться на многопроцессорных системах, или если член данных m_a не выровнен по
границе машинного слова, "родного" для архитектуры, на которой запускается программа.
Советую не искушать судьбу и использовать CRITICAL_SECTION.
Здравствуйте, tripol, Вы писали:
T>Здравствуйте, tripol, Вы писали:
T>И в случае с вопросом топик-стартера можно использовать приведенный класс, T>но только необходимо добавить volatile.
Отключение агрессивной оптимизации тут вряд ли поможет — нечего оптимизировать
Re[2]: вопрос по синхронизации в многопоточной среде
Здравствуйте, A.Lokotkov, Вы писали:
AL>Здравствуйте, sidorov18, Вы писали:
S>>вопрос: S>>может ли быть, что доступ к этой переменной будет во время ее записи и, например, вернется не ее предыдущее(или новое) значение, а что то вроде: S>>старшие 2 байта будут от нового значения, а младшие 2 байта будут от старого?
AL>Процессор какой?
Какой угодно, где стоит винда)
Re[2]: вопрос по синхронизации в многопоточной среде
Здравствуйте, savitar, Вы писали:
S>Здравствуйте, sidorov18, Вы писали:
S>>... S>интересно, а предыдущее значение устраивает?
да. раз не успел... то ладно)
Re[8]: вопрос по синхронизации в многопоточной среде
Здравствуйте, _stun_, Вы писали:
__>Банально — это InterlockedExchange и иже с ней, если мы про Windows. Критические секции и мьютексы, в данном случае — из пушки по воробьям.
Спасибо. Я так понимаю, Критические секции и мьютексы работают медленнее, чем Interlocked ф-ии?
И еще. тут предложили использовать volatile.. поможет ли volatile? компилятор — vs2005.
Re[4]: вопрос по синхронизации в многопоточной среде
Здравствуйте, _stun_, Вы писали:
__>Здравствуйте, tripol, Вы писали:
T>>Здравствуйте, uzhas, Вы писали:
U>>>может
T>>Интересно как, ведь операции процессора являются дискретными, а в данном случае я полагаю T>>используется 32-битный код, следовательно чтение или запись производится одной T>>операцией и следовательно половинное значение получить невозможно.
__>Ну, во-первых, 32хбитный код не обязательно подразумевает 32хразрядную шину данных. Во-вторых, чтение и запись запросто могут быть не в память, а в кеш. И тут вообще может случиться много забавного. Например, первые два байта в одной строке, остальные — в другой.
А скажите пожалуйста, что за кеш?
Re[9]: вопрос по синхронизации в многопоточной среде
Здравствуйте, _stun_, Вы писали:
__>Здравствуйте, tripol, Вы писали:
T>>Здравствуйте, tripol, Вы писали:
T>>И в случае с вопросом топик-стартера можно использовать приведенный класс, T>>но только необходимо добавить volatile.
__>Отключение агрессивной оптимизации тут вряд ли поможет — нечего оптимизировать
Вполне может прооптимизировать такой код:
class A{
long m_a;
public:
long get_a()
{
return m_a;
}
void set_a( long val )
{
m_a = val;
}
};
A a;
void Thread1()
{
a.set_a(1);
}
int main()
{
a.set_a(0);
// start new thread to Thread1()
while(!a.get_a()) // здесь может заинлайнить и без volatile цикл не выйдет
{
}
}
И вообще рекомендуется применять volatile для таких случаев всегда независимо от того,
заоптимизирует данный компилятор или нет.
Re[3]: вопрос по синхронизации в многопоточной среде