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

Вниз

TTread + Terminate.   Найти похожие ветки 

 
Тимохов ©   (2004-04-16 15:05) [0]

Продолжаю изучать потоки и все с этим связанное.

Есть метод TThread.Terminate. Зачем этот метод и как им пользоваться я знаю.
Вопрос по телу этого метода.
У меня в Д6 оно состоит из одной строки FTerminated := True;
Метод Terminate обычно вызывается из одного потока, а обращение к свойству Terminated из другого.
Как видно здесь никаких методов синхронизации не предусмотрено (я не нашел).
Вопрос: почему не возникает проблем многопоточного доступа в переменной?


 
Тимохов ©   (2004-04-16 15:05) [0]

Продолжаю изучать потоки и все с этим связанное.

Есть метод TThread.Terminate. Зачем этот метод и как им пользоваться я знаю.
Вопрос по телу этого метода.
У меня в Д6 оно состоит из одной строки FTerminated := True;
Метод Terminate обычно вызывается из одного потока, а обращение к свойству Terminated из другого.
Как видно здесь никаких методов синхронизации не предусмотрено (я не нашел).
Вопрос: почему не возникает проблем многопоточного доступа в переменной?


 
Reindeer Moss Eater ©   (2004-04-16 15:07) [1]

Нет никакой переменной


 
Reindeer Moss Eater ©   (2004-04-16 15:07) [1]

Нет никакой переменной


 
Тимохов ©   (2004-04-16 15:10) [2]


> Reindeer Moss Eater ©   (16.04.04 15:07) [1]

А FTerminated?
Ну хорошо - атрибутов, так лучше?
Т.е. не понял ответа


 
Тимохов ©   (2004-04-16 15:10) [2]


> Reindeer Moss Eater ©   (16.04.04 15:07) [1]

А FTerminated?
Ну хорошо - атрибутов, так лучше?
Т.е. не понял ответа


 
Reindeer Moss Eater ©   (2004-04-16 15:12) [3]

А почему должны быть проблемы многопоточного доступа?
Это что, ресурсы GDI задевает или еще что?


 
Reindeer Moss Eater ©   (2004-04-16 15:12) [3]

А почему должны быть проблемы многопоточного доступа?
Это что, ресурсы GDI задевает или еще что?


 
Семен Сорокин ©   (2004-04-16 15:13) [4]

Вопрос: почему не возникает проблем многопоточного доступа в переменной?
имхо, этот атрибут из основного потока - только для чтения, ты же не можешь задать Terminated := ... поэтому нет средств для синзронизации.


 
Семен Сорокин ©   (2004-04-16 15:13) [4]

Вопрос: почему не возникает проблем многопоточного доступа в переменной?
имхо, этот атрибут из основного потока - только для чтения, ты же не можешь задать Terminated := ... поэтому нет средств для синзронизации.


 
Reindeer Moss Eater ©   (2004-04-16 15:18) [5]

Он (автор) имел ввиду

procedure TThread.Terminate;
begin
 FTerminated := True;
end;

И все же, откуда мнение, что проблемы должны быть?


 
Reindeer Moss Eater ©   (2004-04-16 15:18) [5]

Он (автор) имел ввиду

procedure TThread.Terminate;
begin
 FTerminated := True;
end;

И все же, откуда мнение, что проблемы должны быть?


 
Тимохов ©   (2004-04-16 15:18) [6]


> имхо, этот атрибут из основного потока - только для чтения,
> ты же

Вызов termiante идет из основного потока, поэтому и изменение идет в коде основного потока.


> Reindeer Moss Eater ©   (16.04.04 15:12) [3]

Но вот арифметическая операция над атрибутом из разных потоков точно требует синхронизации. Т.е. почему для операции присваивания синхронизации не требуется.


 
Тимохов ©   (2004-04-16 15:18) [6]


> имхо, этот атрибут из основного потока - только для чтения,
> ты же

Вызов termiante идет из основного потока, поэтому и изменение идет в коде основного потока.


> Reindeer Moss Eater ©   (16.04.04 15:12) [3]

Но вот арифметическая операция над атрибутом из разных потоков точно требует синхронизации. Т.е. почему для операции присваивания синхронизации не требуется.


 
Reindeer Moss Eater ©   (2004-04-16 15:20) [7]

Но вот арифметическая операция над атрибутом из разных потоков точно требует синхронизации.

Атрибутом КАКИХ классов? Всех? Черта с два.


 
Reindeer Moss Eater ©   (2004-04-16 15:20) [7]

Но вот арифметическая операция над атрибутом из разных потоков точно требует синхронизации.

Атрибутом КАКИХ классов? Всех? Черта с два.


 
Тимохов ©   (2004-04-16 15:31) [8]


> Reindeer Moss Eater ©   (16.04.04 15:20) [7]

Поясняю вопрос.
var
  // глобальная, доступна из основоного потока и доп потока.
  i: int64;

begin
  // в основном потоке ...
  i := 23424323431243142;
end;

присвоение равносильно
mov [ebp-$10],$4d391d86
mov [ebp-$0c],$0053384c

т.е. команды 2, а не одна.

В данном случае основной поток может прерваться и доп поток будет работать не с нужным значением, а только с чатью $4d391d86.

Вы хотите сказать, что и в этом случае не нужна синхронизация?


 
Тимохов ©   (2004-04-16 15:31) [8]


> Reindeer Moss Eater ©   (16.04.04 15:20) [7]

Поясняю вопрос.
var
  // глобальная, доступна из основоного потока и доп потока.
  i: int64;

begin
  // в основном потоке ...
  i := 23424323431243142;
end;

присвоение равносильно
mov [ebp-$10],$4d391d86
mov [ebp-$0c],$0053384c

т.е. команды 2, а не одна.

В данном случае основной поток может прерваться и доп поток будет работать не с нужным значением, а только с чатью $4d391d86.

Вы хотите сказать, что и в этом случае не нужна синхронизация?


 
Семен Сорокин ©   (2004-04-16 15:31) [9]

Тимохов ©   (16.04.04 15:18) [6]
Вызов termiante идет из основного потока, поэтому и изменение идет в коде основного потока.

вот-вот, немного не так выразился, так изменения в самом потоке св-ва Terminate нет!
там только проверка по этому аотрибуту, поэтому проблем совместного доступа не должно быть.


 
Семен Сорокин ©   (2004-04-16 15:31) [9]

Тимохов ©   (16.04.04 15:18) [6]
Вызов termiante идет из основного потока, поэтому и изменение идет в коде основного потока.

вот-вот, немного не так выразился, так изменения в самом потоке св-ва Terminate нет!
там только проверка по этому аотрибуту, поэтому проблем совместного доступа не должно быть.


 
Тимохов ©   (2004-04-16 15:32) [10]


> Семен Сорокин ©   (16.04.04 15:31) [9]

посмотрите 8.
что вы на это скажете?


 
Тимохов ©   (2004-04-16 15:32) [10]


> Семен Сорокин ©   (16.04.04 15:31) [9]

посмотрите 8.
что вы на это скажете?


 
Verg ©   (2004-04-16 15:34) [11]


>  Т.е. почему для операции присваивания синхронизации не
> требуется.


Вот в данном конкретном случае логика работы не может быть нарушена, когда один только один поток присваивает, а другой только проверяет этот флаг. При том переменная в один байт и присваивание ей или проверка ее на что-то происходит в одну машинную команду.


 
Verg ©   (2004-04-16 15:34) [11]


>  Т.е. почему для операции присваивания синхронизации не
> требуется.


Вот в данном конкретном случае логика работы не может быть нарушена, когда один только один поток присваивает, а другой только проверяет этот флаг. При том переменная в один байт и присваивание ей или проверка ее на что-то происходит в одну машинную команду.


 
Reindeer Moss Eater ©   (2004-04-16 15:34) [12]

Тимохов ©

И как эта хрень с твоим вопросом связана?

не говоря уже о том, что FTerminated: Boolean; а не int64


 
Reindeer Moss Eater ©   (2004-04-16 15:34) [12]

Тимохов ©

И как эта хрень с твоим вопросом связана?

не говоря уже о том, что FTerminated: Boolean; а не int64


 
KSergey ©   (2004-04-16 15:35) [13]

> Reindeer Moss Eater ©   (16.04.04 15:07)
> Нет никакой переменной

А для тупых подробнее можно? ;)

> [3] Reindeer Moss Eater ©   (16.04.04 15:12)
> А почему должны быть проблемы многопоточного доступа?
> Это что, ресурсы GDI задевает или еще что?

Это что-то еще. Разве нет? ;)
Да и разве просбемы многопоточности - проблемы лишь в GDI?

> Семен Сорокин ©   (16.04.04 15:13)
> Вопрос: почему не возникает проблем многопоточного доступа
> в переменной?
> имхо, этот атрибут из основного потока - только для чтения,
> ты же не можешь задать Terminated := ... поэтому нет средств
> для синзронизации.

Да, но его код выполняется в рамках основного потока... Т.е. фактически в основном потоке выпоняется это присваивание.

Рискну высказать свой вариант:
В любом случае минимальной единицей выполяемого кода является одна инструкция процессора.
Переменная типа Boolean - это 1 байт. Т.е. ее заполнение/чтение  - это одна команда процессора. Рассмотрим такой сценарий событий: в основном потоке подошли непосредственно к машинной команде записи в эту переменную (ее ячейку памяти) значения 1. В доп потоке подошли к выполнению команды чтения из этой ячейки (метод Get св-ства Terminated). Даже если перед самой записью в основном потоке произойдет переключение на дополнительный - ничего срашного: прочитается значение на данный момент. Если перед самым чтением в доп. потоке произойдет переключение в основной - сколько угодно: пропишется новое значение (в основном) и позже в доп. прочитается новое.

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

Если все вру - прошу прощения.
Надеюсь - поправят.


 
KSergey ©   (2004-04-16 15:35) [13]

> Reindeer Moss Eater ©   (16.04.04 15:07)
> Нет никакой переменной

А для тупых подробнее можно? ;)

> [3] Reindeer Moss Eater ©   (16.04.04 15:12)
> А почему должны быть проблемы многопоточного доступа?
> Это что, ресурсы GDI задевает или еще что?

Это что-то еще. Разве нет? ;)
Да и разве просбемы многопоточности - проблемы лишь в GDI?

> Семен Сорокин ©   (16.04.04 15:13)
> Вопрос: почему не возникает проблем многопоточного доступа
> в переменной?
> имхо, этот атрибут из основного потока - только для чтения,
> ты же не можешь задать Terminated := ... поэтому нет средств
> для синзронизации.

Да, но его код выполняется в рамках основного потока... Т.е. фактически в основном потоке выпоняется это присваивание.

Рискну высказать свой вариант:
В любом случае минимальной единицей выполяемого кода является одна инструкция процессора.
Переменная типа Boolean - это 1 байт. Т.е. ее заполнение/чтение  - это одна команда процессора. Рассмотрим такой сценарий событий: в основном потоке подошли непосредственно к машинной команде записи в эту переменную (ее ячейку памяти) значения 1. В доп потоке подошли к выполнению команды чтения из этой ячейки (метод Get св-ства Terminated). Даже если перед самой записью в основном потоке произойдет переключение на дополнительный - ничего срашного: прочитается значение на данный момент. Если перед самым чтением в доп. потоке произойдет переключение в основной - сколько угодно: пропишется новое значение (в основном) и позже в доп. прочитается новое.

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

Если все вру - прошу прощения.
Надеюсь - поправят.


 
Тимохов ©   (2004-04-16 15:35) [14]


> При том переменная в один байт и присваивание ей или проверка
> ее на что-то происходит в одну машинную команду

Похоже, что вот именно это и является здесь главным.

В присвоении fterminated есть однозначное предположение, что выполнение произойдет в одну команду.


 
Тимохов ©   (2004-04-16 15:35) [14]


> При том переменная в один байт и присваивание ей или проверка
> ее на что-то происходит в одну машинную команду

Похоже, что вот именно это и является здесь главным.

В присвоении fterminated есть однозначное предположение, что выполнение произойдет в одну команду.


 
Семен Сорокин ©   (2004-04-16 15:36) [15]

Тимохов ©   (16.04.04 15:32) [10]
а если так:

var
 // глобальная, доступна из основоного потока и доп потока.
 i: boolean;


 
Семен Сорокин ©   (2004-04-16 15:36) [15]

Тимохов ©   (16.04.04 15:32) [10]
а если так:

var
 // глобальная, доступна из основоного потока и доп потока.
 i: boolean;


 
Verg ©   (2004-04-16 15:38) [16]

Для сравнения: код, который якобы изображает из себя критическую секцию.

while flag do; //
flag := true;  // Вход в "критическую секцию"
// Здесь казалось бы одновременно может "находится" только один поток, который первый обнаружит not flag
flag := false; // Типа выход из "КС"


 
Verg ©   (2004-04-16 15:38) [16]

Для сравнения: код, который якобы изображает из себя критическую секцию.

while flag do; //
flag := true;  // Вход в "критическую секцию"
// Здесь казалось бы одновременно может "находится" только один поток, который первый обнаружит not flag
flag := false; // Типа выход из "КС"


 
Тимохов ©   (2004-04-16 15:38) [17]


> Семен Сорокин ©   (16.04.04 15:36) [15]

Тогда будет все ок.

Вопрос почти снят: спасибо verg и KSergey - они подствердили мои предположения.

Но хотелось бы еще кого-нибудь и св. синих услышать...


 
Тимохов ©   (2004-04-16 15:38) [17]


> Семен Сорокин ©   (16.04.04 15:36) [15]

Тогда будет все ок.

Вопрос почти снят: спасибо verg и KSergey - они подствердили мои предположения.

Но хотелось бы еще кого-нибудь и св. синих услышать...


 
KSergey ©   (2004-04-16 15:42) [18]

Прошу прощения, [13] KSergey ©   (16.04.04 15:35) писалось когда еще не было
[11] Verg ©   (16.04.04 15:34)
[12] Reindeer Moss Eater ©   (16.04.04 15:34)
[14] Тимохов ©   (16.04.04 15:35)

> [12] Reindeer Moss Eater ©   (16.04.04 15:34)
> И как эта хрень с твоим вопросом связана?
> не говоря уже о том, что FTerminated: Boolean; а не int64

Не, ну человек хочет "разобраться что к чему. Законно." (с) ;)
В подробностях.
Так что прошу не уклоняться и ответить на > [8] Тимохов по-нашему, по-программистски: да или нет. ;) (может/не может быть проблем)


 
KSergey ©   (2004-04-16 15:42) [18]

Прошу прощения, [13] KSergey ©   (16.04.04 15:35) писалось когда еще не было
[11] Verg ©   (16.04.04 15:34)
[12] Reindeer Moss Eater ©   (16.04.04 15:34)
[14] Тимохов ©   (16.04.04 15:35)

> [12] Reindeer Moss Eater ©   (16.04.04 15:34)
> И как эта хрень с твоим вопросом связана?
> не говоря уже о том, что FTerminated: Boolean; а не int64

Не, ну человек хочет "разобраться что к чему. Законно." (с) ;)
В подробностях.
Так что прошу не уклоняться и ответить на > [8] Тимохов по-нашему, по-программистски: да или нет. ;) (может/не может быть проблем)


 
Reindeer Moss Eater ©   (2004-04-16 15:42) [19]

procedure TThread.Terminate;
begin
FTerminated := True;
end;

Это, как и любой другой метод кроме Execute выполняется в контексте того потока, который вызвал метод, а не в контексте Execute


 
Reindeer Moss Eater ©   (2004-04-16 15:42) [19]

procedure TThread.Terminate;
begin
FTerminated := True;
end;

Это, как и любой другой метод кроме Execute выполняется в контексте того потока, который вызвал метод, а не в контексте Execute


 
Verg ©   (2004-04-16 15:43) [20]


> Тимохов ©   (16.04.04 15:35) [14]
>
> > При том переменная в один байт и присваивание ей или проверка
>
> > ее на что-то происходит в одну машинную команду
>
> Похоже, что вот именно это и является здесь главным.


В данном, конктретном случае даже если бы эта переменная была бы Int64, то перевод любой составляющей длинного слова в положение ненуль (хоть одной тетрады, хоть одного бита, хоть какой части) будет давать true на проверку
if Var64 <> 0 then
 exit;
И поток завершиться, выйдет из цикла или еще чего там надо... И все, цель достигнута.


 
Verg ©   (2004-04-16 15:43) [20]


> Тимохов ©   (16.04.04 15:35) [14]
>
> > При том переменная в один байт и присваивание ей или проверка
>
> > ее на что-то происходит в одну машинную команду
>
> Похоже, что вот именно это и является здесь главным.


В данном, конктретном случае даже если бы эта переменная была бы Int64, то перевод любой составляющей длинного слова в положение ненуль (хоть одной тетрады, хоть одного бита, хоть какой части) будет давать true на проверку
if Var64 <> 0 then
 exit;
И поток завершиться, выйдет из цикла или еще чего там надо... И все, цель достигнута.


 
Тимохов ©   (2004-04-16 15:44) [21]


> KSergey ©   (16.04.04 15:42) [18]

В 8 я не спрашивал будут или нет проблемы. Я и сам знаю - будут.


> Reindeer Moss Eater ©   (16.04.04 15:42) [19]

Это вообще кому?


 
Тимохов ©   (2004-04-16 15:44) [21]


> KSergey ©   (16.04.04 15:42) [18]

В 8 я не спрашивал будут или нет проблемы. Я и сам знаю - будут.


> Reindeer Moss Eater ©   (16.04.04 15:42) [19]

Это вообще кому?


 
Тимохов ©   (2004-04-16 15:45) [22]


> Verg ©   (16.04.04 15:43) [20]

В данном конкретном случае действительно понятно. Но ведь хочется методику понять: когда нужно делать синхронизацию, когда нет. Вот строки вы же так не рискнюте присваивать? :))))


 
Тимохов ©   (2004-04-16 15:45) [22]


> Verg ©   (16.04.04 15:43) [20]

В данном конкретном случае действительно понятно. Но ведь хочется методику понять: когда нужно делать синхронизацию, когда нет. Вот строки вы же так не рискнюте присваивать? :))))


 
Reindeer Moss Eater ©   (2004-04-16 15:45) [23]

Это на пост который остался высоко вверху.
Не вам


 
Reindeer Moss Eater ©   (2004-04-16 15:45) [23]

Это на пост который остался высоко вверху.
Не вам


 
Romkin ©   (2004-04-16 15:50) [24]

Да какя разница, во сколько команд происходит присвоение? Чужой поток может только присвоить, а собственный - читает значение через terminated. Как бы часто он не читал, переменная изначально выставлена в false, и не важно, будет ли поток ее читать, в то время как доругой ее меняет, или нет. Как поменяет - будет прочитано true.
Вот и все, только два значения, причем чужой поток может выставить только одно из них. Поэтому синхронизация не требуется.


 
Romkin ©   (2004-04-16 15:50) [24]

Да какя разница, во сколько команд происходит присвоение? Чужой поток может только присвоить, а собственный - читает значение через terminated. Как бы часто он не читал, переменная изначально выставлена в false, и не важно, будет ли поток ее читать, в то время как доругой ее меняет, или нет. Как поменяет - будет прочитано true.
Вот и все, только два значения, причем чужой поток может выставить только одно из них. Поэтому синхронизация не требуется.


 
Тимохов ©   (2004-04-16 15:52) [25]


> Romkin ©   (16.04.04 15:50) [24]

С переменной типа booloean вроде разобрались.

А для int64. Что тоже считаете разницы нет?


 
Тимохов ©   (2004-04-16 15:52) [25]


> Romkin ©   (16.04.04 15:50) [24]

С переменной типа booloean вроде разобрались.

А для int64. Что тоже считаете разницы нет?


 
Digitman ©   (2004-04-16 15:57) [26]


> Тимохов ©   (16.04.04 15:05)  


флейм по сабжу не стоит и выеденного яйца

boolean - это байт

инструкция модификации байта не м.б. прервана в связи с мультизадачностью

поток получил квант времени и модифицировал байт памяти ... все ! никто и ничто не прервет инструкцию MOV BYTE PTR...  !!

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


 
Digitman ©   (2004-04-16 15:57) [26]


> Тимохов ©   (16.04.04 15:05)  


флейм по сабжу не стоит и выеденного яйца

boolean - это байт

инструкция модификации байта не м.б. прервана в связи с мультизадачностью

поток получил квант времени и модифицировал байт памяти ... все ! никто и ничто не прервет инструкцию MOV BYTE PTR...  !!

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


 
Тимохов ©   (2004-04-16 15:58) [27]

Сим ответом и удовлетворю свой интерес.
Всем спасибо.


 
Тимохов ©   (2004-04-16 15:58) [27]

Сим ответом и удовлетворю свой интерес.
Всем спасибо.


 
KSergey ©   (2004-04-16 15:59) [28]

> [26] Digitman ©   (16.04.04 15:57)
> флейм по сабжу не стоит и выеденного яйца

И не надо разводить!
неужели жалко сказать: вот тут будет, тут нет. И все. ;)


 
KSergey ©   (2004-04-16 15:59) [28]

> [26] Digitman ©   (16.04.04 15:57)
> флейм по сабжу не стоит и выеденного яйца

И не надо разводить!
неужели жалко сказать: вот тут будет, тут нет. И все. ;)


 
Digitman ©   (2004-04-16 15:59) [29]


> А для int64. Что тоже считаете разницы нет?


есть. и  - ощутимая !

ощутимая до поры, пока исполняется 32-разрядная ОС на машине с 64-разрядным ЦП


 
Digitman ©   (2004-04-16 15:59) [29]


> А для int64. Что тоже считаете разницы нет?


есть. и  - ощутимая !

ощутимая до поры, пока исполняется 32-разрядная ОС на машине с 64-разрядным ЦП


 
Тимохов ©   (2004-04-16 16:02) [30]


> Digitman ©   (16.04.04 15:59) [29]

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

Почему у нас нет конкурса на самого полезного игрока? :)))


 
Тимохов ©   (2004-04-16 16:02) [30]


> Digitman ©   (16.04.04 15:59) [29]

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

Почему у нас нет конкурса на самого полезного игрока? :)))


 
Digitman ©   (2004-04-16 16:04) [31]


> на самого полезного игрока


смотря во что и на что играть) ...

шары катать ? на "шары" о ставках базар вести ?)

кажись, это и так здесь в избытке)))


 
Digitman ©   (2004-04-16 16:04) [31]


> на самого полезного игрока


смотря во что и на что играть) ...

шары катать ? на "шары" о ставках базар вести ?)

кажись, это и так здесь в избытке)))


 
Romkin ©   (2004-04-16 16:12) [32]

Тимохов ©  (16.04.04 15:52) [25] Байты, биты... Если бы было объявлено как longBOOL - тоже нет разницы.
Ведь состояние может измениться только на одно другое, и возвращаться обратно не будет. Хоть сколько раз установи в true, придет время - прочитают.
То есть, это очень узкая вещь... Но здравый смысл поможет :))
Есть переменная, никто по-умолчанию не запрещает одновременно читать/писать ее любому числу потоков. ТАк?
Можно запретить писать, можно запретить читать. Вопрос - когда.
Очень просто: Если при чтении во время записи возможно чтение не того, что надо - надо синхронизировать. Это - при сложных объектах. Если у тебя простая переменная, в которую один поток только пишет (строка - составная!), то понятно, что другие потоки пусть ее читают сколько влезет. Касательно int64  - я бы не рисковал, на старых процессорах вполне возможна запись ее за два такта, и чтение в промежутке между ними. Если допустимо - ок...


 
Romkin ©   (2004-04-16 16:12) [32]

Тимохов ©  (16.04.04 15:52) [25] Байты, биты... Если бы было объявлено как longBOOL - тоже нет разницы.
Ведь состояние может измениться только на одно другое, и возвращаться обратно не будет. Хоть сколько раз установи в true, придет время - прочитают.
То есть, это очень узкая вещь... Но здравый смысл поможет :))
Есть переменная, никто по-умолчанию не запрещает одновременно читать/писать ее любому числу потоков. ТАк?
Можно запретить писать, можно запретить читать. Вопрос - когда.
Очень просто: Если при чтении во время записи возможно чтение не того, что надо - надо синхронизировать. Это - при сложных объектах. Если у тебя простая переменная, в которую один поток только пишет (строка - составная!), то понятно, что другие потоки пусть ее читают сколько влезет. Касательно int64  - я бы не рисковал, на старых процессорах вполне возможна запись ее за два такта, и чтение в промежутке между ними. Если допустимо - ок...


 
Verg ©   (2004-04-16 17:05) [33]


> Romkin ©   (16.04.04 16:12) [32]



> возможна запись ее за два такта,


Такт или два на однопрцессорной машине - значение не имеет, т.к. аппаратные прерывания (за чсет которых, по-сути и происходит передача управление thread менеджеру) возможны только между командами (исключение - цепочечные операции).
А вот в многопроцессорной машине - там да, там всякое может быть.
Вот для этого и существют в API специальные ф-ции из серии
InterLocked..... Xсhange, Increment, Decrement и т.п.


 
Verg ©   (2004-04-16 17:05) [33]


> Romkin ©   (16.04.04 16:12) [32]



> возможна запись ее за два такта,


Такт или два на однопрцессорной машине - значение не имеет, т.к. аппаратные прерывания (за чсет которых, по-сути и происходит передача управление thread менеджеру) возможны только между командами (исключение - цепочечные операции).
А вот в многопроцессорной машине - там да, там всякое может быть.
Вот для этого и существют в API специальные ф-ции из серии
InterLocked..... Xсhange, Increment, Decrement и т.п.


 
Игорь Шевченко ©   (2004-04-16 23:57) [34]


> А вот в многопроцессорной машине - там да, там всякое может
> быть.


Конечно. Один процесс начал в память байт записывать, записал четыре бита, а в это время другой процессор начал читать и прочитал такую ерунду...


 
Игорь Шевченко ©   (2004-04-16 23:57) [34]


> А вот в многопроцессорной машине - там да, там всякое может
> быть.


Конечно. Один процесс начал в память байт записывать, записал четыре бита, а в это время другой процессор начал читать и прочитал такую ерунду...


 
KSergey ©   (2004-04-17 07:10) [35]

> [34] Игорь Шевченко ©   (16.04.04 23:57)
> Конечно. Один процесс начал в память байт записывать, записал
> четыре бита, а в это время другой процессор начал читать
> и прочитал такую ерунду...

Мммм... Это шутка, я надеюсь??


 
KSergey ©   (2004-04-17 07:10) [35]

> [34] Игорь Шевченко ©   (16.04.04 23:57)
> Конечно. Один процесс начал в память байт записывать, записал
> четыре бита, а в это время другой процессор начал читать
> и прочитал такую ерунду...

Мммм... Это шутка, я надеюсь??


 
Verg ©   (2004-04-17 13:07) [36]


> KSergey ©   (17.04.04 07:10) [35]


Я тоже не понял....


 
Verg ©   (2004-04-17 13:07) [36]


> KSergey ©   (17.04.04 07:10) [35]


Я тоже не понял....


 
nikkie ©   (2004-04-17 14:54) [37]

а можно я тоже задам вопрос про TThread? про Synchronize?

вам не кажется, что то, что Synchronize является методом TThread - это неудобно? ситуация такая: создается потомок TThread, который выполняет какую-то работу. достаточно сложную и разноплановую. для чего вызывает уже не свои методы а методы каких-то других объектов. а те - еще чьи-нибудь методы. и вот где-то на нижнем уровне требуется реализовать нечто - логирование, подсчет траффика или еще что, что требует синхронизации. откуда взять TThread? передавать во все используемые объекты? не слишком ли жирно?

как бы вы выкручивались бы в этой ситуации? я склоняюсь к тому, чтобы синхронизацию сделать просто посылкой сообщения главному окну. собственно почти так и сделано в D5 (в D6 просто страх какой-то творится - видимо это для единообразия с Kylix-ом), только сообщение посылается некоему ThreadWindow. кстати, при такой реализации и не понятно, зачем было бы не сделать Synchronize классовым методом или обычной процедурой. другое кстати - Synchronize в D5, как я понимаю, исполняет метод в контексте не основного потока, а в контексте первого потока, создавшего объект типа TThread (а, например, такая ситуация - потоки уже есть, хотя TThread еще никто не создавал - легко может возникнуть в DLL).


 
nikkie ©   (2004-04-17 14:54) [37]

а можно я тоже задам вопрос про TThread? про Synchronize?

вам не кажется, что то, что Synchronize является методом TThread - это неудобно? ситуация такая: создается потомок TThread, который выполняет какую-то работу. достаточно сложную и разноплановую. для чего вызывает уже не свои методы а методы каких-то других объектов. а те - еще чьи-нибудь методы. и вот где-то на нижнем уровне требуется реализовать нечто - логирование, подсчет траффика или еще что, что требует синхронизации. откуда взять TThread? передавать во все используемые объекты? не слишком ли жирно?

как бы вы выкручивались бы в этой ситуации? я склоняюсь к тому, чтобы синхронизацию сделать просто посылкой сообщения главному окну. собственно почти так и сделано в D5 (в D6 просто страх какой-то творится - видимо это для единообразия с Kylix-ом), только сообщение посылается некоему ThreadWindow. кстати, при такой реализации и не понятно, зачем было бы не сделать Synchronize классовым методом или обычной процедурой. другое кстати - Synchronize в D5, как я понимаю, исполняет метод в контексте не основного потока, а в контексте первого потока, создавшего объект типа TThread (а, например, такая ситуация - потоки уже есть, хотя TThread еще никто не создавал - легко может возникнуть в DLL).


 
Игорь Шевченко ©   (2004-04-17 21:21) [38]

KSergey ©   (17.04.04 07:10)
Verg ©   (17.04.04 13:07)

Вопрос на засыпку: имеется двухпроцессорная система. На одном процессе один поток выполняет машинную команду записи байта в оперативную память, на другом процессоре другой поток в это же время выполняет чтение байта из оперативной памяти по этому адресу. Что будет записано и что будет прочитано ?


 
Игорь Шевченко ©   (2004-04-17 21:21) [38]

KSergey ©   (17.04.04 07:10)
Verg ©   (17.04.04 13:07)

Вопрос на засыпку: имеется двухпроцессорная система. На одном процессе один поток выполняет машинную команду записи байта в оперативную память, на другом процессоре другой поток в это же время выполняет чтение байта из оперативной памяти по этому адресу. Что будет записано и что будет прочитано ?


 
Тимохов ©   (2004-04-18 10:58) [39]


> Игорь Шевченко ©   (17.04.04 21:21) [38]

Не томите, скажите сами ? :)))))))))


 
Тимохов ©   (2004-04-18 10:58) [39]


> Игорь Шевченко ©   (17.04.04 21:21) [38]

Не томите, скажите сами ? :)))))))))


 
Digitman ©   (2004-04-18 11:26) [40]


> Игорь Шевченко


а про кэш-арбитр ты почему-то умолчал)


 
Digitman ©   (2004-04-18 11:26) [40]


> Игорь Шевченко


а про кэш-арбитр ты почему-то умолчал)


 
Anatoly Podgoretsky ©   (2004-04-18 11:35) [41]

В данном конкретном примере FTerminated является приватным полем объекта, ни один другой поток не имеет прямого доступа до него. В каком бы контенсте не был вызван метод, сам поток пишет и читает жто поле, к тому же атомарная операция.


 
Anatoly Podgoretsky ©   (2004-04-18 11:35) [41]

В данном конкретном примере FTerminated является приватным полем объекта, ни один другой поток не имеет прямого доступа до него. В каком бы контенсте не был вызван метод, сам поток пишет и читает жто поле, к тому же атомарная операция.


 
Verg ©   (2004-04-18 12:32) [42]


> Игорь Шевченко ©   (17.04.04 21:21) [38]
> KSergey ©   (17.04.04 07:10)
> Verg ©   (17.04.04 13:07)
>
> Вопрос на засыпку: имеется двухпроцессорная система. На
> одном процессе один поток выполняет машинную команду записи
> байта в оперативную память, на другом процессоре другой
> поток в это же время выполняет чтение байта из оперативной
> памяти по этому адресу. Что будет записано и что будет прочитано
> ?


Интереснее другое. Два потока пытаются одновременно инкрементировать ячейку памяти (inc [esi]). Я думаю, что вот тут как раз и будет четко видна разница однопроцессорной от многопроцессорной.
>1 процессора - есть вероятность, что ячейка синкрементируется на единицу, хотя по логике - должна на 2, т.к. между чтением старого значения и записью нового (+1) шина свободна и другой процессор может прочитать старое значение.

Ты это имел ввиду?

вот для этого и пишут lock inc [esi] (InterLockedIncrement).


 
Verg ©   (2004-04-18 12:32) [42]


> Игорь Шевченко ©   (17.04.04 21:21) [38]
> KSergey ©   (17.04.04 07:10)
> Verg ©   (17.04.04 13:07)
>
> Вопрос на засыпку: имеется двухпроцессорная система. На
> одном процессе один поток выполняет машинную команду записи
> байта в оперативную память, на другом процессоре другой
> поток в это же время выполняет чтение байта из оперативной
> памяти по этому адресу. Что будет записано и что будет прочитано
> ?


Интереснее другое. Два потока пытаются одновременно инкрементировать ячейку памяти (inc [esi]). Я думаю, что вот тут как раз и будет четко видна разница однопроцессорной от многопроцессорной.
>1 процессора - есть вероятность, что ячейка синкрементируется на единицу, хотя по логике - должна на 2, т.к. между чтением старого значения и записью нового (+1) шина свободна и другой процессор может прочитать старое значение.

Ты это имел ввиду?

вот для этого и пишут lock inc [esi] (InterLockedIncrement).


 
Verg ©   (2004-04-18 12:39) [43]


> Что будет записано и что будет прочитано
> > ?


В байте до этого было число Y.
Записано будет то, что первый поток хотел записать (X).
А вот второй поток может причитать и X и Y с вероятностью 50/50.

Правильно?


 
Verg ©   (2004-04-18 12:39) [43]


> Что будет записано и что будет прочитано
> > ?


В байте до этого было число Y.
Записано будет то, что первый поток хотел записать (X).
А вот второй поток может причитать и X и Y с вероятностью 50/50.

Правильно?


 
Master Denis   (2004-04-18 19:30) [44]

А не проще написать прогу, которая будет только присваиваить скажем $ffffff... а затем тудаже $0000..., а в доп. потоке читать эту переменную.
Если хть раз прочитает что-нить отличное от этих двух значений - значит вполне возможно перекличение между потоками в момент записи части переменнной....
Сейчас пойду писать...


 
Master Denis   (2004-04-18 19:30) [44]

А не проще написать прогу, которая будет только присваиваить скажем $ffffff... а затем тудаже $0000..., а в доп. потоке читать эту переменную.
Если хть раз прочитает что-нить отличное от этих двух значений - значит вполне возможно перекличение между потоками в момент записи части переменнной....
Сейчас пойду писать...


 
Романов Р.В. ©   (2004-04-19 08:19) [45]

Anatoly Podgoretsky ©   (18.04.04 11:35) [41]
Потрясающая оперативность. Ответ на вопрос спустя 2 суток после этого:

Тимохов ©   (16.04.04 15:58) [27]
Сим ответом и удовлетворю свой интерес.
Всем спасибо.


Браво...


 
Романов Р.В. ©   (2004-04-19 08:19) [45]

Anatoly Podgoretsky ©   (18.04.04 11:35) [41]
Потрясающая оперативность. Ответ на вопрос спустя 2 суток после этого:

Тимохов ©   (16.04.04 15:58) [27]
Сим ответом и удовлетворю свой интерес.
Всем спасибо.


Браво...


 
KSergey ©   (2004-04-19 09:02) [46]

> [38] Игорь Шевченко ©   (17.04.04 21:21)
> Вопрос на засыпку: имеется двухпроцессорная система. На
> одном процессе один поток выполняет машинную команду записи
> байта в оперативную память, на другом процессоре другой
> поток в это же время выполняет чтение байта из оперативной
> памяти по этому адресу. Что будет записано и что будет прочитано?

Каюсь, я не знаю как именно организовываются многопроцессорные системы, однако уверен (во всяком случе сделал бы так, если бы меня допустили ;), что при доступе обоих процессоров к одной ячейке памяти - один и них блокиреутся нафиг до высвобождения оной.
А вот что происходит при работе несколькоих потоков, каждый на своем процессоре, когда один из потоков входит в критическую секцию - это хороший вопрос: пока один процессор - он просто не переключается, а когда более одного? Не блокировать же остальные... Мда, тут я не знаю... Может расскажете?

Но все же мне думается, что не приходится задумываться о том один процессор или несколько в системе, во всяком случае при программировании под готовую OC: в противном случае, уверен, в книгах кроме проблем с потоками упоминались бы еще и проблемы написания кода под многопроцессорные системы, а мне такое не встречалось. Может не те книжки читал?


 
KSergey ©   (2004-04-19 09:02) [46]

> [38] Игорь Шевченко ©   (17.04.04 21:21)
> Вопрос на засыпку: имеется двухпроцессорная система. На
> одном процессе один поток выполняет машинную команду записи
> байта в оперативную память, на другом процессоре другой
> поток в это же время выполняет чтение байта из оперативной
> памяти по этому адресу. Что будет записано и что будет прочитано?

Каюсь, я не знаю как именно организовываются многопроцессорные системы, однако уверен (во всяком случе сделал бы так, если бы меня допустили ;), что при доступе обоих процессоров к одной ячейке памяти - один и них блокиреутся нафиг до высвобождения оной.
А вот что происходит при работе несколькоих потоков, каждый на своем процессоре, когда один из потоков входит в критическую секцию - это хороший вопрос: пока один процессор - он просто не переключается, а когда более одного? Не блокировать же остальные... Мда, тут я не знаю... Может расскажете?

Но все же мне думается, что не приходится задумываться о том один процессор или несколько в системе, во всяком случае при программировании под готовую OC: в противном случае, уверен, в книгах кроме проблем с потоками упоминались бы еще и проблемы написания кода под многопроцессорные системы, а мне такое не встречалось. Может не те книжки читал?


 
Anatoly Podgoretsky ©   (2004-04-19 09:10) [47]

Романов Р.В. ©   (19.04.04 08:19) [45]
Да какая разница когда, иногда бывают ответы и несколько месяцев спустя.


 
Anatoly Podgoretsky ©   (2004-04-19 09:10) [47]

Романов Р.В. ©   (19.04.04 08:19) [45]
Да какая разница когда, иногда бывают ответы и несколько месяцев спустя.


 
Игорь Шевченко ©   (2004-04-19 11:59) [48]

[40] Digitman ©   (18.04.04 11:26)

:)) Ну вот, такой вопрос был хороший...

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

Verg ©   (18.04.04 12:39)

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

Префикс Lock используется обычно тогда, когда между чтением и модификацией ячейки памяти с памятью не должно проиходить посторонних операций со стороны других компонент аппаратуры, в том числе и другого процессора. Поэтому чаще всего этот префикс использовался с машинной командой xchg, сейчас чаще всего с командой xadd.


 
Игорь Шевченко ©   (2004-04-19 11:59) [48]

[40] Digitman ©   (18.04.04 11:26)

:)) Ну вот, такой вопрос был хороший...

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

Verg ©   (18.04.04 12:39)

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

Префикс Lock используется обычно тогда, когда между чтением и модификацией ячейки памяти с памятью не должно проиходить посторонних операций со стороны других компонент аппаратуры, в том числе и другого процессора. Поэтому чаще всего этот префикс использовался с машинной командой xchg, сейчас чаще всего с командой xadd.


 
Тимохов ©   (2004-04-19 12:08) [49]


> Anatoly Podgoretsky ©   (18.04.04 11:35) [41]


> В данном конкретном примере FTerminated является приватным
> полем объекта, ни один другой поток не имеет прямого доступа
> до него. В каком бы контенсте не был вызван метод, сам поток
> пишет и читает жто поле, к тому же атомарная операция.

Анатолий.
Что-то странное вы говорите. Какая разница, что поле приватное. Реально читают и пишут то разные потоки.

Скорее всего здесь дело в атамарности.


 
Тимохов ©   (2004-04-19 12:08) [49]


> Anatoly Podgoretsky ©   (18.04.04 11:35) [41]


> В данном конкретном примере FTerminated является приватным
> полем объекта, ни один другой поток не имеет прямого доступа
> до него. В каком бы контенсте не был вызван метод, сам поток
> пишет и читает жто поле, к тому же атомарная операция.

Анатолий.
Что-то странное вы говорите. Какая разница, что поле приватное. Реально читают и пишут то разные потоки.

Скорее всего здесь дело в атамарности.



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

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

Наверх




Память: 0.76 MB
Время: 0.047 c
3-1081933782
nv_
2004-04-14 13:09
2004.05.09
Поиск в подстановочном поле


3-1081941938
SergeyB
2004-04-14 15:25
2004.05.09
Не генерируется событие TDatabase.OnAfterDisconnect


6-1079679862
slgeo
2004-03-19 10:04
2004.05.09
Не возвращается количество полученных байт в блокирующисокетах???


7-1080563938
Alex-drob
2004-03-29 16:38
2004.05.09
Закрыть другую программу


14-1081972905
l_igor
2004-04-15 00:01
2004.05.09
Windows XP





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский