Показать сообщение отдельно

  #3628  
Старый 26.08.2009, 12:01
slesh
Познавший АНТИЧАТ
Регистрация: 05.03.2007
Сообщений: 1,985
С нами: 10097606

Репутация: 3349


По умолчанию

void Thread( void *a)
{
int mid;

mid = id++;
Get(IntToStr(1000+mid).c_str());
}
Или как вариант можеш юзать синхронизацию при изменениии. или интерлоки юзать
mid = InterlockedIncrement(&id) - 1;
т.е. id увеличится 100% на 1 и вернется его текущее значение. от которого ты отнимиш 1 чтобы получить предыдущее. Антерлок онснован на атомарном доступе. т.е. блокировка шины памяти идет и в этоге никто другой не сможет изменить значение.
В этоге такая конструкция (без учета того что это вызов апишки)представляет собой такой код:
Код:
mov ecx,[esp+4] ; ecx = адресу переменной X
mov eax,1 
lock xadd [ecx],eax; блокирем шину памяти, прибавляем значение регистра eax к тому участку памяти где хранится X а предыдущее значение закидываем в eax. 
inc eax ; увеличиваем eax на 1 - хз зачем MS это делает. сам не понимаю. Типа вернет не старое значение а новое. тупость
т.е. даже если после lock xadd [ecx],eax выполнение получит другой поток, то всё будет нормально потому что значение хранится в регисте, а при смене потока автоматом сохраняются значения всех регистров. И потом уже данные будут браться не их паременной X а из регистра eax.
темболее что lock xadd [ecx],eax не может прерваться на половине выполнения. И даже если у тебя многопроцессорная система, то всё равно потоки другова процессора не смогут в этотже момент времяни изменить значение переменной.
Вот такаявот хитро-простая синхронизация может быть сделана
 
Ответить с цитированием