Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.048 c
11-1144318313
Dodfr
2006-04-06 14:11
2007.01.21
MHFontDialog return bad font height


4-1157629234
apollon604
2006-09-07 15:40
2007.01.21
Переключение окон в панели задач


3-1162280807
Patrick
2006-10-31 10:46
2007.01.21
Компонент для Oracle


4-1157415257
Psychedelic
2006-09-05 04:14
2007.01.21
EnumDisplaySettingsEx - crash


15-1167416437
Kolan
2006-12-29 21:20
2007.01.21
Где бы контролы для графиков взять?





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