Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];

Вниз

Опять о синхронизации в потоках.   Найти похожие ветки 

 
Alexander Panov ©   (2005-06-04 21:38) [0]

Исходный и скомпилированный код:


 i:=0;
 xor eax,eax
 mov [i],eax

 b:=True;
 mov byte ptr [b],$01

 i1:=1;
 mov [i1],$00000001

 b1:=False;
 mov byte ptr [b1],$00

 i1 := i;
 mov eax,[i]
 mov [i1],eax

 b1 := b;
 mov al,[$0045ccac]
 mov [$0045ccad],al



Вопрос:

Потокобезопасно ли выполнение каждой инструкции исходного кода в приведенном выше примере?


 
SPeller ©   (2005-06-04 21:50) [1]

Потокобезопасна только одна машинная инструкция. Инструкция языка, состоящая из нескольких машинных команд - НЕ потоко-безопасна.


 
Alexander Panov ©   (2005-06-04 22:07) [2]

SPeller ©   (04.06.05 21:50) [1]
Потокобезопасна только одна машинная инструкция. Инструкция языка, состоящая из нескольких машинных команд - НЕ потоко-безопасна.


Таким образом, защищать Integer- и Boolean- переменные тоже необходимо при многопоточной работе?;)


 
Alexander Panov ©   (2005-06-04 22:08) [3]

Забыл добавить, как орпределены переменные:

var
  i, i1: Integer;
  b, b1: Boolean;


Все переменные глобальные.


 
Kerk ©   (2005-06-04 23:23) [4]

Alexander Panov ©   (04.06.05 22:07) [2]
Таким образом, защищать Integer- и Boolean- переменные тоже необходимо при многопоточной работе?;)


Защищать необходимо любые данные объявленные используемые глобально. Независимо от типа.


 
Alexander Panov ©   (2005-06-04 23:41) [5]

Kerk ©   (04.06.05 23:23) [4]
Защищать необходимо любые данные объявленные используемые глобально. Независимо от типа.


Я-то согласен, но помнится, что кто-то утверждал, что такие операции являются атомарными.


 
Dezmond   (2005-06-05 00:01) [6]

Alexander Panov ©   (04.06.05 21:38)

Работа с однобайтовыми переменными потокаезопасна, их синхронизируют аппаратные арбитры, по крайней мере мне так Digitman говорил...


 
Eraser ©   (2005-06-05 00:08) [7]

Dezmond = Eraser

Вот думаю, ник менять или нет...


 
Alexander Panov ©   (2005-06-05 00:19) [8]

Dezmond   (05.06.05 0:01) [6]
Работа с однобайтовыми переменными потокаезопасна


Однако пример кода показывает другое.

b1 := b;
mov al,[$0045ccac]
  В этот момент система может переключиться на выполнение другого потока и он может изменить значение по адресу $0045ccac

mov [$0045ccad],al  //Здесь получим неверное значение.


 
Eraser ©   (2005-06-05 00:22) [9]

Alexander Panov ©   (05.06.05 00:19) [8]

Я точно не знаю "механики" работы процессора, но думаю ЧеловекЦифра не зря так написал, я ещё переспросил тогда...
Возможно эта проблема решается на аппаратном уровне, хотя ума не приложу как.


 
-=XP=- ©   (2005-06-05 03:02) [10]

При переключении между потоками, процессор сохраняет состояние регистров для каждого потока. Таким образом, при возвращении к потоку, его работа будет продолжена.

И в примере:
mov eax,[i]
mov [i1],eax

нет ничего потокоопасного. Не важно, на какой инструкции поток заснет, ожидая выполнения других потоков. Важно другое, то, что переменная i1 примет значение, равное i. Порчи данных при этом не будет. Именно это важно.

Для примера, сравните:

type
 TMyRec = record
   i1: integer;
   i2: integer;
 end;
var
 MR1, MR2: TMyRec;
begin
 MR1.i1 := 100;  // 1
 MR1.i2 := 100;  // 2
 MR2 := MR1;     // 3
end;


Операции 1, 2 являются атомарными. Не важно, когда поток будет временно приторможен процессором. Важно то, что по очереди в MR1.i1 окажется значение 100, в MR.i2 окажется значение 100. И речь в данном случае именно о числе 100. Именно об этом идет речь. В ходе операций 1 и 2 в поля i1 и i2 будут записано 100. Ни 20, ни 50, ни 98. Только 100. В этом и заключается атомарность операции. Процессор никогда не запишет в поле i1 или i2 часть битов числа 100, а затем переключится на выполнение другого потока. Или все число 100, или ничего. Вот в этом атомарность.

А вот операция 3 не является атомарной. И может сложится ситуация, когда переключение между потоками будет произведено в момент выполнения операции 3. И в переменной MR2 будет не (i1: 100; i2: 100), а (i1: 100; i2: 0) или (i1: 100; i2: -57), что, впрочем, зависит от начального значения MR2. Логично, что в этот момент другой поток, полагающийся на значение MR2, будет заниматься ерундой, производя какие-то там вычисления с этой переменной.
То же относится и к совокупности операций 1 и 2 - вместе они потоконебезопасны, так как поток может притормозить между ними.

Но, опять же таки, смотря как взглянуть - мало ли для чего используются данные записей MR1 и MR2. На самом деле в данной ситуации все очень сильно зависит от контекста.

Говоря в общих чертах - код, изменяющий несколько логически взаимно связанных переменных, или даже одну переменную, операции с которой являются неатомарными, - потоконебезопасный.

Вот строки символов (особенно динамические строки Delphi) - практически без контекста - потоконебезопасны. Если один поток начнет переписывать значение длины строки (то, которое по 0-му смещению), собираясь потом выделить под новую строку память, и, сразу же после этого, другой поток обратится к этой строке - то суждено ему работать с неправильно распределенной памятью, опираясь на новое значение длины строки. Я уже не говорю про подсчет количества ссылок.

А представьте, что произойдет, если во время выполнения MyPersistent1.Assign(MyPersistent2) произойдет переключение между потоками? Это ж никто не знает (кроме автора класса), что в методе AssignTo происходит, какие данные копируются, и когда ядро ОС решит переключить этот поток на какой-то другой (а этого уже точно никто не знает).

Так что приведенные в вопросе примеры - потокобезопасны, если между собой никак логически не связаны.


 
Суслик ©   (2005-06-05 10:26) [11]


>  Alexander Panov ©   (04.06.05 21:38)

Саш, ты того, почитал бы что-нить по теме потоков (плюс к тому, что уже прочел). Например, Рихтер "win для профессионалов" четвертое издание, стр. 140-141.


 
Igorek ©   (2005-06-05 12:13) [12]

А что такое потокобезопасность?


 
Eraser ©   (2005-06-05 13:30) [13]

А что такое потокобезопасность?

Это гарантия того, что в определённый момент N данные Z доступны только ОДНОМУ потоку.


 
Alexander Panov ©   (2005-06-05 14:00) [14]

Суслик ©   (05.06.05 10:26) [11]

Вот-вот.
Снова читал Рихтера, потому и возник такой вопрос.

-=XP=- ©   (05.06.05 3:02) [10]

Измени на
MR1.i1 := 100;  // 1   на  MR1.i1 := 0;

Операция сразу перестанет быть атомарной.
В момент присвоения поток может быть прерван. Если во втором потоке выполняется операция сравнения, которая завист от MR1.i1, то результат сравнения будет не тот, который ожидается.


 
Igorek ©   (2005-06-05 23:07) [15]

Eraser ©   (05.06.05 13:30) [13]
Это гарантия того, что в определённый момент N данные Z доступны только ОДНОМУ потоку.

Тогда не существует непотокобезопасного кода на 1 проц. платформах.



Страницы: 1 вся ветка

Форум: "Потрепаться";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.039 c
8-1110129109
anamal
2005-03-06 20:11
2005.06.29
Как убрать мигание?


1-1118063196
Иван П.
2005-06-06 17:06
2005.06.29
Первое-последнее число текущего месяца в DateTimePicker


9-1111275692
Green_Templar
2005-03-20 02:41
2005.06.29
TDXImageList


1-1117526237
KillerToxa
2005-05-31 11:57
2005.06.29
Глюки TRichEdit и TJvRichEdit


4-1115586895
Wer
2005-05-09 01:14
2005.06.29
Del programm





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский