![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Теоритический вопрос про потоки и контекст
Anatoly Podgoretsky © (2006-11-23 14:28:00)Интересует следующая вещь, поскольку информация противоречивая.
Допустим есть следующий код, значимые куски
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;
С третьем случае все одназначно, в контексте потока, а первые два?
Anatoly Podgoretsky (2006-11-23 16:25:00) [41]> MBo (23.11.2006 16:02:23) [23]
Мой здравый смысл подсказывает, что в контексте потока, но автор утверждает обратное, вот поэтому я и озаботился. Сейчас у меня реализовано по его рекомендации, в Execute, но я сейчас делаю рефакторинг с резким увеличением производительности и одновременно возрастает сложность, то варианты 1 и 2 меня очень интересуют, особенно один. Тогда программа очень сильно упращается и становится более управляемой. Я хочу большинство переменных перенести в модуль данных, создавать его в Create при создании потока и не беспокоиться об уничтожении. Каждый поток будет иметь свой модуль данных и тоже относится и к соединениям, каждое клиентское соединение будет иметь свой модуль данных.
Раннии эксперименты меня заставили перенести переменные из определения модуля в метод Execute.
После этого все стало стабильно, но не удобно. Это были следующие компоненты THttpCli, TAbsTable и TSringList.
Сейчас я перехожу вместо TAbsTable на АДО компоненты
Но меня интересует не практический вопрос, а теоритический
MBo (2006-11-23 16:02:00) [42]>Где ссылка на объект хранится — какая, собственно, разница?
Интересно, что в моем примере, если вывести адрес (IntToHex(Integer(@SL),8)) локальной переменной главного потока (стек главного потока уменьшен до предела), StringList-а, созданного в Thread.Create, и локального для Execute StringList, то получается:
0006F520 009BDD18 003FFF60
Сами объекты, конечно, лежат в общей куче, и адреса их близкие
IntToHex(Integer(SL),8)
009BDCD8 009A0E40 009A0E00
Джо (2006-11-23 15:58:00) [43]> [21] Anatoly Podgoretsky © (23.11.06 15:57)
> Да я проблемы обойду, не это интересует, а первые два слова
> темы.
Какие именно: "Теоритический вопрос" или "Интересует следующая"? :)
Anatoly Podgoretsky (2006-11-23 15:57:00) [44]> Джо (23.11.2006 15:42:20) [20]
Да я проблемы обойду, не это интересует, а первые два слова темы.
Джо (2006-11-23 15:42:00) [45]> [19] Anatoly Podgoretsky © (23.11.06 15:40)
> > Джо (23.11.2006 15:30:17) [17]
>
> TStringList приведен только для примера, кроме него еще
> есть следующие компоненты - THttpCli и АДО компоненты.
Ну, тогда и нужно смотреть их методы, на предмет наличия в них всяких "выкрутасов", если таковые имеются :)
Anatoly Podgoretsky (2006-11-23 15:40:00) [46]> Джо (23.11.2006 15:30:17) [17]
TStringList приведен только для примера, кроме него еще есть следующие компоненты - THttpCli и АДО компоненты.
Anatoly Podgoretsky (2006-11-23 15:38:00) [47]> Eraser (23.11.2006 15:29:16) [16]
Как ты это представляешь, создавать самого себя не создав самого себя.
И речь шла не про его компоненты, а про вообще компоненты.
Джо (2006-11-23 15:30:00) [48]> [14] Anatoly Podgoretsky © (23.11.06 15:18)
> > Джо (23.11.2006 15:05:11) [11]
>
> Франсуа Пьетте сказал, что выполняться будет в контексте
> того потока, где создан объект
Странное, однако мнение. Где ссылка на объект хранится — какая, собственно, разница?
Еще понятно было бы, если бы в TStringList.Get какие-то были манипуляции для "переключения" контекстов, но ведь их там нет.
Eraser (2006-11-23 15:29:00) [49]> [15] Anatoly Podgoretsky © (23.11.06 15:22)
может он имел ввиду, что его сетевые компоненты желательно создавать в том же потоке, в котором собираетесь их использовать?
Anatoly Podgoretsky (2006-11-23 15:22:00) [50]> MBo (23.11.2006 15:07:12) [12]
Вот это уже конкретнее, но для его компонентов (ICS), пока я не перенес SL в Execute это не работало. Вожможно это особенность его компонент. Но его слова "не важно где используется, выполняется (используется) в контексте того потока где создано". Метод Create выполняется в контексте главного потока.
Вот меня сомнения и мучают.
Anatoly Podgoretsky (2006-11-23 15:18:00) [51]> Джо (23.11.2006 15:05:11) [11]
Франсуа Пьетте сказал, что выполняться будет в контексте того потока, где создан объект и посоветовал все переместить в Execute - это помогло, но это мне не очень подходит, для простых систем еще ни чего, а для сложных с разными методами и процедурами не очень, поскольку переменные локальны для Execute, а не для объекта. Пока у меня реализовано по его рекомендации, но я думаю об варианте 1 и 2
Плохо, что пока никто не подошел, кто это достоверно знает.
Anatoly Podgoretsky (2006-11-23 15:15:00) [52]> clickmaker (23.11.2006 15:03:10) [10]
Неправильно, я рассмотрю обоснования или приму их или отвергну.
MBo (2006-11-23 15:07:00) [53]Эксперимент показал (окно 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;
Джо (2006-11-23 15:05:00) [54]> [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). А почему оно должно выполняться в каком-то другом контексте?
clickmaker (2006-11-23 15:03:00) [55]
> хотя бы не достоверной информацией, но с обоснованием
вот этот подход мне по душе. "Ответ неверный, но интересный", так? ))
Anatoly Podgoretsky (2006-11-23 14:57:00) [56]> Сергей М. (23.11.2006 14:45:08) [8]
Ну так кто ни будь обладает достоверной информацией?
Или хотя бы не достоверной информацией, но с обоснованием.
Сергей М. (2006-11-23 14:45:00) [57]
> Знал бы ты какие ответы на это вопрос я слышал
Да уж знаю)... Поверь уж)
Anatoly Podgoretsky (2006-11-23 14:44:00) [58]> clickmaker (23.11.2006 14:33:03) [3]
Китайская очепятка
S := SL[0]
Anatoly Podgoretsky (2006-11-23 14:44:00) [59]> Джо (23.11.2006 14:32:02) [2]
Конечно не скомпилируется, я же предупредил. Если не понятен сокращеный код, то вот пояснение
1. SL расколожен внутри класса, создается в контексте главного потока (Create)
2. SL расколожен внутри класса, создается в Execute
3. SL расколожен внутри Execute, создается в Execute, доступ в контексте потока
Вопрос такой, в контексте какого потока будет доступ в Execute для вариантов 1. и 2.
C третьим все ясно.
clickmaker (2006-11-23 14:43:00) [60]
> Знал бы ты какие ответы на это вопрос я слышал
все кроме [2] ? ))