![]() |
Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply |
![]() ![]() ![]() |
|
BofA |
|
|||
Новичок Профиль Группа: Участник Сообщений: 10 Регистрация: 7.7.2006 Репутация: нет Всего: нет |
Добрый день.
Возник глупый вопрос слеующего типа. Допустим, есть два потока, один из них записывает данные в глобальную переменную, а другой читает их. Никаких методов синхронизации не используется. Правильно ли я понимаю, что читающий поток будет получать последнее записанное до чтения значение (т.е. не может случиться такого, что потоки одновременно обратятся к переменной и из-за конфликта читающий поток получит мусор)? Подразумевается, что переменная - обычный Integer (правильно ли я понимаю, что в случае, к примеру, с record, читающий поток может получить запись, содержащую половину предыдущей и половину обновлённой записи в случае конфликта?) |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
даже с простым integer небезопасно. Юзай Interlocked-функции
-------------------- Обижено школьников: 8 |
|||
|
||||
ReInit |
|
|||
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 14.11.2008 Репутация: 1 Всего: 1 |
bems,
глупости, чтение и запись дворда потокопезопасна даже в мультипроцессорной среде... Добавлено через 2 минуты и 59 секунд
Нет, читающий поток получит всегда определенное значение переменной. Недозаписанных двордов быть не может. |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 16 Всего: 459 |
Я себе думаю так, все семафоры и прочие глобальные объекты синхронизации ни что иное как обычные объекты в системной области. Если один поток меняет состояние глобального объекта, то другой в это время может его читать. И все происходит правильно. Получается если тип совпадает с разрядностью регистра и операция занимает один такт, то все будет верно, однако используя высокоуровневый язык нельзя гарантировать что операция займет один такт.
Вообще, часто встречаются ситуации когда некоторые данные неявно связанны между собой, потому безобидная на первый взгляд операция может привести к непредсказуемым результатам, поскольку 2 потока меняют связанные между собой параметры одновременно. В связи с этим лучше избежать несинхронизированного доступа. Если нужен многопоточный счетчик используйте семафор. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
CodeMonkey |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 16 Всего: 89 |
Синхронизация потоков в пользовательском режиме
Добавлено через 4 минуты и 25 секунд
Вообще-то даже Interlocked функции работают не атомарно для не выровненных даннных. А что уж говорить про обычные операции... -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
|||
|
||||
ReInit |
|
||||
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 14.11.2008 Репутация: 1 Всего: 1 |
CodeMonkey,
Да, конечно я имел ввиду выровненные данные. Delphi впрочем, по умолчанию их выравнивает.
Количество тактов тут не причем. Даже на ЯВУ дворд не будет считываться/записываться побайтно или пословно, он будет считываться/записываться именно двордом, и это будет происходит атомарно (опять оговорюсь - для выровненных данных).
??? Это сообщение отредактировал(а) ReInit - 9.1.2009, 01:10 |
||||
|
|||||
Riply |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Комодератор Сообщений: 572 Регистрация: 27.3.2007 Где: St. Petersburg Репутация: 21 Всего: 32 |
||||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 16 Всего: 459 |
Я имел ввиду тот случай когда 2 потока читают и пишут в одну переменную. Классический пример, когда идут 3 асмовские команды и в зависимости от того на какой команде прервали получается разный результат. Если всего одна команда inc, а не 3 то все будет верно. Я сейчас не вспомню пример, но где-то у Петровича было. Одна переменная вычисляется через другую двумя потоками, вроде как оба потока делают безопасные операции, но результат неверный. Нужно курить маны ![]() -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
CodeMonkey |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 16 Всего: 89 |
Помимо всего прочего, Interlocked-функции включают в себя memory fence, чего точно нет у обычного чтения. По ссылке же пример. Хотя там значения получаются "целиком", но не те, какие мы ожидаем. Ещё пример можно увидеть здесь (пункт "Свободное от блокировок переупорядочение").
-------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
|||
|
||||
RinOSpro |
|
|||
Unregistered |
Процитирую один документик посвященный многопоточности
![]()
Казалось бы что может быть проще? К несчастью, даже этот простой код может вызвать проблемы, если два потока используют его для увеличения общей переменной A. Этот единственный оператор Паскаля транслируется в три действия на ассемблерном уровне. Чтение A из ячейки памяти в регистр процессора. Увеличение регистра процессора на 1. Запись содержимого регистра процессора в ячейку памяти A. ![]() Однако нет никакой гарантии, что все именно так и произойдет. Закон Мерфи гласит, что может случиться следующее: ![]() В этом случае А увеличивается не на два, а только на единицу. Конечно, если А является положением индикатора, то это, скорее всего, не проблема, но если А - что-нибудь более важное, подобно счетчику количества элементов в списке, тогда жди беды. Если общая переменная является указателем, то можно наткнуться на самые разные неприятные результаты. Это иногда называют race condition (конфликт, конкуренция потоков). Подробнее читайте в первой ссылке или см вложение, там в формате doc. Присоединённый файл ( Кол-во скачиваний: 2 ) ![]() |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: WinAPI и системное программирование" | |
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |