Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.01.21;
Скачать: CL | DM;

Вниз

Теоритический вопрос про потоки и контекст   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.069 c
15-1166914973
Denisich
2006-12-24 02:02
2007.01.21
Установка acs24


4-1157991343
alexandrine
2006-09-11 20:15
2007.01.21
SHFileOpStruct


8-1148541508
Der Nechk@ssoff
2006-05-25 11:18
2007.01.21
PlayList


15-1167745139
Parus
2007-01-02 16:38
2007.01.21
ASP


15-1167164837
kroner
2006-12-26 23:27
2007.01.21
Регулярные выражения в delphi