Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Теоритический вопрос про потоки и контекст


Страницы:   1 2 3 4

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;

С третьем случае все одназначно, в контексте потока, а первые два?


Slym_RO   (2006-11-24 13:20:00) [21]

Ганю! 1 всегда в контексте ОСНОВНОГО потока


Slym_RO   (2006-11-24 13:19:00) [22]

2,3 - в контексте потока, накакать где хранится ссылка на обект
1 - сложнее:
1.1. в контексте потока
constructor TT.Create;
begin
inherited Create(True);
SL := TStringList.Create;
Resume;
end;


1.1. в контексте ОСНОВНОГОпотока
constructor TT.Create;
begin
SL := TStringList.Create;
inherited Create(True);
Resume;
end;


Anatoly Podgoretsky   (2006-11-24 13:06:00) [23]

> guav  (24.11.2006 12:44:40)  [40]

Именно так у меня и сделано, возможно только что сетевые компоненты так нельзя создавать, возможно они что то внутри делают с текущим потоком, тоже для базы.
Автор утверждает, что и создание и сама переменнаядолжны находиться в методе Execute. Более того упирает на слово сама переменная, а не создание или использование.
Именно это меня и смущает. Но я в текущей ситуации уже не могут так, поскольку есть много других методов, ну не передавать же мне туда переменную? А их не одна. Есть модуль данных, есть сетевые компоненты, есть компоненты БД и другие переменные, которые должны быть доступны и в главном потоке. Ну ладно я переместил сетевые компоненты и компоненты БД в модуль данных и если будут проблемы, то буду передавать ссылку на модуль данных.

Мне бы было проще и удобнее, если бы я мог объявить все в секции private, не беспокоясь об их уничтожение и доступности.
Я сейчас не могу проверить технически, поскольку идет полная переделка структуры и поиск оптимального варианта. Через несколько дней я смогу подойти к трассировке.

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

Более того его утверждение нашло физическое подтверждение, перенос переменной сняло вопрос.


guav   (2006-11-24 12:56:00) [24]

> [30] Anatoly Podgoretsky ©   (23.11.06 17:06)
> Автор утверждает, что первостепенным явлется в контексте
> какого потока создается, а не в контексте какого используется.

"сама переменная" создаётся для всего процесса, даже если она создаётся в стеке потока (имеется ввиду "настоящая" переменная, а не threadvar). Т.е. потоки ей пофиг.
Выделение памяти под указатель сделано потокобезопасным и может осуществлятся из любого потока, в самой RTL есть пример выделения в одном потоке и совобождения в другом.

А вот для кода может быть и не всё равно, ему смена контекста может повредить, если там использован например GetCurrentThreadId для заполнения поля класса. Т.е. контекст вызова конструктора может играть роль.


guav   (2006-11-24 12:44:00) [25]

> На время выполнения TThead.Create в последних весриях Delphi
> новый (создаваемый) поток вообще спит.

... а в не-последних делают так (привожу не псевдокод, а код, и Вы тоже код приводите, его читать легче, а то [2])
constructor TMyThead.Create;
Begin
 inherited Create(True); // создаём остановленным
 SL := TStringList.Create;
 ...
 Resume; // вот тут он пробуждается.
end;


Вроде даже в справке это разжевано...


guav   (2006-11-24 12:40:00) [26]

> [6] Anatoly Podgoretsky ©   (23.11.06 14:44)


> C третьим все ясно.

Со вторым тоже, тоже из создаваемого потока, ничем от второго не отличается.
Первый из создающего. На время выполнения TThead.Create в последних весриях Delphi новый (создаваемый) поток вообще спит.

Не верите, смотрите генофонд и вызывайте GetCurrentThreadId


Anatoly Podgoretsky   (2006-11-23 18:23:00) [27]

> Leonid Troyanovsky  (23.11.2006 18:05:34)  [34]

Чистый стринг лист, чистый HTTPCli, ну и ранее был Absolute Database - все они расчитаны на работу в потоках, сейчас перевожу на АДО
За счет переноса объявлений в Execute проблема была полностью решена. Но сейчас я хочу сильно пересмотреть структуру программы, применить индивидуальные модули данных для каждого потока и желательно его объявить и создавать в Thread.Create
На модуле данных будут лежать вышеуказаные компоненты.


Anatoly Podgoretsky   (2006-11-23 18:17:00) [28]

> Джо  (23.11.2006 17:46:33)  [33]

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


Anatoly Podgoretsky   (2006-11-23 18:16:00) [29]

> Eraser  (23.11.2006 17:19:31)  [31]

AV это аргумент или нет?


Anatoly Podgoretsky   (2006-11-23 18:14:00) [30]

> Джо  (23.11.2006 17:05:29)  [29]

Это из почты, которую я ежедневно уничтожаю


Leonid Troyanovsky   (2006-11-23 18:05:00) [31]


> Anatoly Podgoretsky ©   (23.11.06 14:28)  

>  SL: TStringList


Если речь идет о чистом TStringList, а не о неких потомках,
то место его создания значения не имеет.
Т.е., он, как раз, является примером thread-safe VCL.
Правда, анализировал исходники еще в D2.

Конечно, в случае с потомками, это легко опровергнуть.

--
Regards, LVT.


Джо   (2006-11-23 17:46:00) [32]

> [32] Romkin ©   (23.11.06 17:31)
> Конечно, не важно, где лежит указатель. Вот только
> кроме указателя есть куча вещей, которые зависят от потока

Насчет этого я (и не только я, кажется) уже говорил. Анатолий берет ответственность на себя, утверждая, что с этим он сам разберется :)


Romkin   (2006-11-23 17:31:00) [33]

Логика, логика... ADO, скорее всего, надо создавать в том потоке, в котором используешь: там интерфейсы СОМ. И не так просто передавать интерфейс между потоками ;)
TTimer нужно создавать в execute - там сообщение. Которое придет в тот поток, который зарегистрирован...
И тд. Конечно, не важно, где лежит указатель. Вот только кроме указателя есть куча вещей, которые зависят от потока


Eraser   (2006-11-23 17:19:00) [34]

> [30] Anatoly Podgoretsky ©   (23.11.06 17:06)


> Если посмотреть на вариант 1 и 2, то там находится не в
> Execute и главный Сreate выполняется в контексте главного
> потока.

правильно, но, к примеру для TStringList, как и для 99% компонетов это нормально.

> Второй вариант я создаю в Execute, но сама переменная создана
> в контексте главного потока. Автор утверждает

я тут вижу противоречие :)

> Моя логика с этим не соглашается.
> Поведение показывает, что моя логика неверная.

а можно пример, уж очень заинтриговали )


Anatoly Podgoretsky   (2006-11-23 17:06:00) [35]

> Eraser  (23.11.2006 16:32:27)  [27]

Если посмотреть на вариант 1 и 2, то там находится не в Execute и главный Сreate выполняется в контексте главного потока. Второй вариант я создаю в Execute, но сама переменная создана в контексте главного потока. Автор утверждает, что первостепенным явлется в контексте какого потока создается, а не в контексте какого используется.

Вот об этом и есть вопрос.
Моя логика с этим не соглашается.
Поведение показывает, что моя логика неверная.


Джо   (2006-11-23 17:05:00) [36]

> [28] Anatoly Podgoretsky ©   (23.11.06 17:03)
> > Джо  (23.11.2006 16:29:26)  [26]
>
> Я уже сказал, что моя логика протестует, автор утверждает
> обратное.

Анатолий, а не могли бы вы привести полную цитату, да еще и с контекстом? Возможно, неверный перевод, да мало ли что.


Anatoly Podgoretsky   (2006-11-23 17:03:00) [37]

> Джо  (23.11.2006 16:29:26)  [26]

Я уже сказал, что моя логика протестует, автор утверждает обратное. Подтверждения ни тому ни другому по этому вопросу мне не встречалось.
Вопрос я вроде четко поставил, что именно интересует и в каком контесте, допольнительные уточнения тоже сделал.


Eraser   (2006-11-23 16:32:00) [38]

> [24] Anatoly Podgoretsky ©   (23.11.06 16:25)


> Но меня интересует не практический вопрос, а теоритический

1. то что находится в ф-ции Execute по определению выполняется в доп. потоке. Вот и вся теория )

2. где вызывать конструктор? для TSringList могу ответить - все равно где.
а вот для сетевых или, что вероятнее БД компонентов разница може быть, но тут уж нужно смотреть реализацию самих компонентов.


Джо   (2006-11-23 16:29:00) [39]

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


Anatoly Podgoretsky   (2006-11-23 16:25:00) [40]

> Джо  (23.11.2006 15:58:22)  [22]

Вопрос начинается со слов Теоритический вопрос


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо