Форум: "Основная";
Текущий архив: 2007.01.21;
Скачать: [xml.tar.bz2];
ВнизТеоритический вопрос про потоки и контекст Найти похожие ветки
← →
Anatoly Podgoretsky © (2006-11-23 14:28) [0]Интересует следующая вещь, поскольку информация противоречивая.
Допустим есть следующий код, значимые куски
Thead = TThead
SL: TStringList
end;
TThead.Create;
Begin
SL := TStringList.Create;
end;
TThead.Execute;
Begin
SL := TStringList.Create;
end;
TThead.Execute;
var
SL: TStringList;
Begin
SL := TStringList.Create;
end;
В контексте какого потока будет выполняться следующий код, для каждого из трех вариантов, если Create вызывается в главном потоке?
TThead.Execute;
Begin
SL := SL[0]
end;
С третьем случае все одназначно, в контексте потока, а первые два?
← →
Сергей М. © (2006-11-23 14:31) [1]Толя, и это ТЫ вопрошаешь ?!!!!!
да не поверю) ...
Провокация ?!
← →
Джо © (2006-11-23 14:32) [2]> SL := SL[0]
Анатолий, ведь это даже не скомпилируется.
← →
clickmaker © (2006-11-23 14:33) [3]
> SL := SL[0]
а что это за загадочная строка?
← →
Anatoly Podgoretsky © (2006-11-23 14:41) [4]> Сергей М. (23.11.2006 14:31:01) [1]
А что простой вопрос задал, так быстро переместим его в Начинающие.
Знал бы ты какие ответы на это вопрос я слышал :-)
← →
clickmaker © (2006-11-23 14:43) [5]
> Знал бы ты какие ответы на это вопрос я слышал
все кроме [2] ? ))
← →
Anatoly Podgoretsky © (2006-11-23 14:44) [6]> Джо (23.11.2006 14:32:02) [2]
Конечно не скомпилируется, я же предупредил. Если не понятен сокращеный код, то вот пояснение
1. SL расколожен внутри класса, создается в контексте главного потока (Create)
2. SL расколожен внутри класса, создается в Execute
3. SL расколожен внутри Execute, создается в Execute, доступ в контексте потока
Вопрос такой, в контексте какого потока будет доступ в Execute для вариантов 1. и 2.
C третьим все ясно.
← →
Anatoly Podgoretsky © (2006-11-23 14:44) [7]> clickmaker (23.11.2006 14:33:03) [3]
Китайская очепятка
S := SL[0]
← →
Сергей М. © (2006-11-23 14:45) [8]
> Знал бы ты какие ответы на это вопрос я слышал
Да уж знаю)... Поверь уж)
← →
Anatoly Podgoretsky © (2006-11-23 14:57) [9]> Сергей М. (23.11.2006 14:45:08) [8]
Ну так кто ни будь обладает достоверной информацией?
Или хотя бы не достоверной информацией, но с обоснованием.
← →
clickmaker © (2006-11-23 15:03) [10]
> хотя бы не достоверной информацией, но с обоснованием
вот этот подход мне по душе. "Ответ неверный, но интересный", так? ))
← →
Джо © (2006-11-23 15:05) [11]> [6] Anatoly Podgoretsky © (23.11.06 14:44)
> > Джо (23.11.2006 14:32:02) [2]
>
> Конечно не скомпилируется, я же предупредил. Если не понятен
> сокращеный код, то вот пояснение
>
> 1. SL расколожен внутри класса, создается в контексте главного
> потока (Create)
> 2. SL расколожен внутри класса, создается в Execute
> 3. SL расколожен внутри Execute, создается в Execute, доступ
> в контексте потока
Все три — будут выполнятся в контексте потока (того, в котором Execute). А почему оно должно выполняться в каком-то другом контексте?
← →
MBo © (2006-11-23 15:07) [12]Эксперимент показал (окно Thread Status в BDS), что для всех случаев - в доп. потоке
TT = class(TThread)
SL: TStringList;
constructor Create;
procedure Execute; override;
end;
procedure TForm16.Button1Click(Sender: TObject);
begin
T:= TT.Create; //breakpoint 1
end;
{ TT }
constructor TT.Create;
begin
inherited Create(True);
SL := TStringList.Create;
Resume;
end;
procedure TT.Execute;
var
S: string;
// SL: TStringList;
begin
// SL := TStringList.Create;
SL.Add("Yeah");
SL.Add("Ndfg");
s:= SL[0]; // breakpoint 2
SendMessage(Form16.Handle, WM_USER, 0, Integer(s));
SL.Free;
end;
← →
Anatoly Podgoretsky © (2006-11-23 15:15) [13]> clickmaker (23.11.2006 15:03:10) [10]
Неправильно, я рассмотрю обоснования или приму их или отвергну.
← →
Anatoly Podgoretsky © (2006-11-23 15:18) [14]> Джо (23.11.2006 15:05:11) [11]
Франсуа Пьетте сказал, что выполняться будет в контексте того потока, где создан объект и посоветовал все переместить в Execute - это помогло, но это мне не очень подходит, для простых систем еще ни чего, а для сложных с разными методами и процедурами не очень, поскольку переменные локальны для Execute, а не для объекта. Пока у меня реализовано по его рекомендации, но я думаю об варианте 1 и 2
Плохо, что пока никто не подошел, кто это достоверно знает.
← →
Anatoly Podgoretsky © (2006-11-23 15:22) [15]> MBo (23.11.2006 15:07:12) [12]
Вот это уже конкретнее, но для его компонентов (ICS), пока я не перенес SL в Execute это не работало. Вожможно это особенность его компонент. Но его слова "не важно где используется, выполняется (используется) в контексте того потока где создано". Метод Create выполняется в контексте главного потока.
Вот меня сомнения и мучают.
← →
Eraser © (2006-11-23 15:29) [16]> [15] Anatoly Podgoretsky © (23.11.06 15:22)
может он имел ввиду, что его сетевые компоненты желательно создавать в том же потоке, в котором собираетесь их использовать?
← →
Джо © (2006-11-23 15:30) [17]> [14] Anatoly Podgoretsky © (23.11.06 15:18)
> > Джо (23.11.2006 15:05:11) [11]
>
> Франсуа Пьетте сказал, что выполняться будет в контексте
> того потока, где создан объект
Странное, однако мнение. Где ссылка на объект хранится — какая, собственно, разница?
Еще понятно было бы, если бы в TStringList.Get какие-то были манипуляции для "переключения" контекстов, но ведь их там нет.
← →
Anatoly Podgoretsky © (2006-11-23 15:38) [18]> Eraser (23.11.2006 15:29:16) [16]
Как ты это представляешь, создавать самого себя не создав самого себя.
И речь шла не про его компоненты, а про вообще компоненты.
← →
Anatoly Podgoretsky © (2006-11-23 15:40) [19]> Джо (23.11.2006 15:30:17) [17]
TStringList приведен только для примера, кроме него еще есть следующие компоненты - THttpCli и АДО компоненты.
← →
Джо © (2006-11-23 15:42) [20]> [19] Anatoly Podgoretsky © (23.11.06 15:40)
> > Джо (23.11.2006 15:30:17) [17]
>
> TStringList приведен только для примера, кроме него еще
> есть следующие компоненты - THttpCli и АДО компоненты.
Ну, тогда и нужно смотреть их методы, на предмет наличия в них всяких "выкрутасов", если таковые имеются :)
← →
Anatoly Podgoretsky © (2006-11-23 15:57) [21]> Джо (23.11.2006 15:42:20) [20]
Да я проблемы обойду, не это интересует, а первые два слова темы.
← →
Джо © (2006-11-23 15:58) [22]> [21] Anatoly Podgoretsky © (23.11.06 15:57)
> Да я проблемы обойду, не это интересует, а первые два слова
> темы.
Какие именно: "Теоритический вопрос" или "Интересует следующая"? :)
← →
MBo © (2006-11-23 16:02) [23]>Где ссылка на объект хранится — какая, собственно, разница?
Интересно, что в моем примере, если вывести адрес (IntToHex(Integer(@SL),8)) локальной переменной главного потока (стек главного потока уменьшен до предела), StringList-а, созданного в Thread.Create, и локального для Execute StringList, то получается:
0006F520 009BDD18 003FFF60
Сами объекты, конечно, лежат в общей куче, и адреса их близкие
IntToHex(Integer(SL),8)
009BDCD8 009A0E40 009A0E00
← →
Anatoly Podgoretsky © (2006-11-23 16:25) [24]> MBo (23.11.2006 16:02:23) [23]
Мой здравый смысл подсказывает, что в контексте потока, но автор утверждает обратное, вот поэтому я и озаботился. Сейчас у меня реализовано по его рекомендации, в Execute, но я сейчас делаю рефакторинг с резким увеличением производительности и одновременно возрастает сложность, то варианты 1 и 2 меня очень интересуют, особенно один. Тогда программа очень сильно упращается и становится более управляемой. Я хочу большинство переменных перенести в модуль данных, создавать его в Create при создании потока и не беспокоиться об уничтожении. Каждый поток будет иметь свой модуль данных и тоже относится и к соединениям, каждое клиентское соединение будет иметь свой модуль данных.
Раннии эксперименты меня заставили перенести переменные из определения модуля в метод Execute.
После этого все стало стабильно, но не удобно. Это были следующие компоненты THttpCli, TAbsTable и TSringList.
Сейчас я перехожу вместо TAbsTable на АДО компоненты
Но меня интересует не практический вопрос, а теоритический
← →
Anatoly Podgoretsky © (2006-11-23 16:25) [25]> Джо (23.11.2006 15:58:22) [22]
Вопрос начинается со слов Теоритический вопрос
← →
Джо © (2006-11-23 16:29) [26]Ну, тогда для начала, Анатолий, попробуйте теоретически показать, отчего бы этому коду выполняться в ином потоке? Ведь очевидно же (я допускаю, что ошибочно) считать, что, раз никаких телодвижений для переключения контекста не делается, то и само-собой ничего не произойдет.
← →
Eraser © (2006-11-23 16:32) [27]> [24] Anatoly Podgoretsky © (23.11.06 16:25)
> Но меня интересует не практический вопрос, а теоритический
1. то что находится в ф-ции Execute по определению выполняется в доп. потоке. Вот и вся теория )
2. где вызывать конструктор? для TSringList могу ответить - все равно где.
а вот для сетевых или, что вероятнее БД компонентов разница може быть, но тут уж нужно смотреть реализацию самих компонентов.
← →
Anatoly Podgoretsky © (2006-11-23 17:03) [28]> Джо (23.11.2006 16:29:26) [26]
Я уже сказал, что моя логика протестует, автор утверждает обратное. Подтверждения ни тому ни другому по этому вопросу мне не встречалось.
Вопрос я вроде четко поставил, что именно интересует и в каком контесте, допольнительные уточнения тоже сделал.
← →
Джо © (2006-11-23 17:05) [29]> [28] Anatoly Podgoretsky © (23.11.06 17:03)
> > Джо (23.11.2006 16:29:26) [26]
>
> Я уже сказал, что моя логика протестует, автор утверждает
> обратное.
Анатолий, а не могли бы вы привести полную цитату, да еще и с контекстом? Возможно, неверный перевод, да мало ли что.
← →
Anatoly Podgoretsky © (2006-11-23 17:06) [30]> Eraser (23.11.2006 16:32:27) [27]
Если посмотреть на вариант 1 и 2, то там находится не в Execute и главный Сreate выполняется в контексте главного потока. Второй вариант я создаю в Execute, но сама переменная создана в контексте главного потока. Автор утверждает, что первостепенным явлется в контексте какого потока создается, а не в контексте какого используется.
Вот об этом и есть вопрос.
Моя логика с этим не соглашается.
Поведение показывает, что моя логика неверная.
← →
Eraser © (2006-11-23 17:19) [31]> [30] Anatoly Podgoretsky © (23.11.06 17:06)
> Если посмотреть на вариант 1 и 2, то там находится не в
> Execute и главный Сreate выполняется в контексте главного
> потока.
правильно, но, к примеру для TStringList, как и для 99% компонетов это нормально.
> Второй вариант я создаю в Execute, но сама переменная создана
> в контексте главного потока. Автор утверждает
я тут вижу противоречие :)
> Моя логика с этим не соглашается.
> Поведение показывает, что моя логика неверная.
а можно пример, уж очень заинтриговали )
← →
Romkin © (2006-11-23 17:31) [32]Логика, логика... ADO, скорее всего, надо создавать в том потоке, в котором используешь: там интерфейсы СОМ. И не так просто передавать интерфейс между потоками ;)
TTimer нужно создавать в execute - там сообщение. Которое придет в тот поток, который зарегистрирован...
И тд. Конечно, не важно, где лежит указатель. Вот только кроме указателя есть куча вещей, которые зависят от потока
← →
Джо © (2006-11-23 17:46) [33]> [32] Romkin © (23.11.06 17:31)
> Конечно, не важно, где лежит указатель. Вот только
> кроме указателя есть куча вещей, которые зависят от потока
Насчет этого я (и не только я, кажется) уже говорил. Анатолий берет ответственность на себя, утверждая, что с этим он сам разберется :)
← →
Leonid Troyanovsky © (2006-11-23 18:05) [34]
> Anatoly Podgoretsky © (23.11.06 14:28)
> SL: TStringList
Если речь идет о чистом TStringList, а не о неких потомках,
то место его создания значения не имеет.
Т.е., он, как раз, является примером thread-safe VCL.
Правда, анализировал исходники еще в D2.
Конечно, в случае с потомками, это легко опровергнуть.
--
Regards, LVT.
← →
Anatoly Podgoretsky © (2006-11-23 18:14) [35]> Джо (23.11.2006 17:05:29) [29]
Это из почты, которую я ежедневно уничтожаю
← →
Anatoly Podgoretsky © (2006-11-23 18:16) [36]> Eraser (23.11.2006 17:19:31) [31]
AV это аргумент или нет?
← →
Anatoly Podgoretsky © (2006-11-23 18:17) [37]> Джо (23.11.2006 17:46:33) [33]
Конечно разберусь и даже потоки не требуются, я их применил, что бы быстро сделать приложение. Во втором рефакторинге наверно откажусь от них, надо только поработать.
← →
Anatoly Podgoretsky © (2006-11-23 18:23) [38]> Leonid Troyanovsky (23.11.2006 18:05:34) [34]
Чистый стринг лист, чистый HTTPCli, ну и ранее был Absolute Database - все они расчитаны на работу в потоках, сейчас перевожу на АДО
За счет переноса объявлений в Execute проблема была полностью решена. Но сейчас я хочу сильно пересмотреть структуру программы, применить индивидуальные модули данных для каждого потока и желательно его объявить и создавать в Thread.Create
На модуле данных будут лежать вышеуказаные компоненты.
← →
guav © (2006-11-24 12:40) [39]> [6] Anatoly Podgoretsky © (23.11.06 14:44)
> C третьим все ясно.
Со вторым тоже, тоже из создаваемого потока, ничем от второго не отличается.
Первый из создающего. На время выполнения TThead.Create в последних весриях Delphi новый (создаваемый) поток вообще спит.
Не верите, смотрите генофонд и вызывайте GetCurrentThreadId
← →
guav © (2006-11-24 12:44) [40]> На время выполнения TThead.Create в последних весриях Delphi
> новый (создаваемый) поток вообще спит.
... а в не-последних делают так (привожу не псевдокод, а код, и Вы тоже код приводите, его читать легче, а то [2])constructor TMyThead.Create;
Begin
inherited Create(True); // создаём остановленным
SL := TStringList.Create;
...
Resume; // вот тут он пробуждается.
end;
Вроде даже в справке это разжевано...
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2007.01.21;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.042 c