Форум: "Основная";
Текущий архив: 2004.02.17;
Скачать: [xml.tar.bz2];
ВнизСоздание объектов для потока Найти похожие ветки
← →
KSergey (2004-02-06 07:41) [0]Вот и у меня вопрос по потокам небольшенький ;)
Пусть для работы потока нужны какие-то объекты (невизуальные). Как грамотнее: создать и уничтожить их в TMyThread.Execute, или можно создавать/уничтожать в конструкторе/деструкторе TMyThread?
Ведь конструктор/деструктор работает в основном потоке, а использоваться объекты получается будут в дополнительном. Так можно ли создавать их в конструкторе?
Единственное, что я понял - так это то, что в случае создания в конструкторе необходимо, конечно же, вызывать его (вернее предка) с параметром CreateSuspended=TRUE, и лишь в конце конструктора вызывать Resume.
Но как делать "грамотнее"? ;)
PS
Одновременная работа с создаваемыми объектами из основного и доп. потока не требуется.
← →
MBo (2004-02-06 07:49) [1]Да, можно в конструкторе.
Suspended - не обязательно.
Resume же вызывается не из конструктора.
← →
Verg (2004-02-06 09:48) [2]Десруктор вызывается в контексте разрушаемого потока если
у него установлено FreeOnTerminate;
> Единственное, что я понял - так это то, что в случае создания
> в конструкторе необходимо, конечно же, вызывать его (вернее
> предка) с параметром CreateSuspended=TRUE, и лишь в конце
> конструктора вызывать Resume.
> Но как делать "грамотнее"? ;)
Можно и так, а можно и сяк:
constructor TAnyThread.Create;
begin
// Здесь создаем все необходимые объекты и устанавливаем флаги
inherited Create(false);
end;
← →
jack128 (2004-02-06 09:58) [3]я предпочитаю все делать в Execute, поскольку в конструкторе класса тоже есть какой то код и он выполняется в контексте основного потока, а потом ты вызываешь методы объекта в доп. потоке - это в некоторых случаях может привести к некоректной работе объекта..
← →
KSergey (2004-02-06 10:03) [4]> [1] MBo © (06.02.04 07:49)
> Да, можно в конструкторе.
А грамотно? Или сиренево?
> Suspended - не обязательно.
Вообще-то к таким выводам (по поводу Rsume) я пришел вот на основании чего: когда я делал CreateSuspended=FALSE, то Execute иногда вызывалась с AV защитой памяти при обращении к адресу 0. Во всяком случае при отладке я на такое точно напарывался (иду по шагам в конструкторе (первым его оператором Inherited), а тут вдруг вылетает указанное AV среди кода Execute при обращении к несозданному (понятно, т.к. создается в конструкторе) объекту.
Ну я и предположил, что собственно поток (в понятии виндовс) создается и стартует именно в конструкторе TTheard.
Или я что-то недопонял и сделал вообще неверные выводы?
← →
MBo (2004-02-06 10:08) [5]>поток (в понятии виндовс) создается и стартует именно в конструкторе TTheard.
Да, но если inherited Create - последний оператор конструктора, то не вижу причин для ошибок.
← →
KSergey (2004-02-06 10:56) [6]> [5] MBo © (06.02.04 10:08)
> >поток (в понятии виндовс) создается и стартует именно в
> конструкторе TTheard.
> Да, но если inherited Create - последний оператор конструктора,
> то не вижу причин для ошибок.
Если последний - то да
но есть "дурацкая" привычка вызывать родительский конструктор первым операторов, а деструктор (в деструкторе ;) - последним ;)
Впрочем, я понял.
Спасибо всем.
← →
Тимохов (2004-02-06 11:06) [7]
> но есть "дурацкая" привычка вызывать родительский конструктор
> первым операторов
Ну если сам знаешь, что дурацкая, почему не отучишься.
Коль конструктор начал выполняться - он ничем не отличается от обычного метода.
← →
Verg (2004-02-06 11:21) [8]
> но есть "дурацкая" привычка вызывать родительский конструктор
> первым операторов, а деструктор (в деструкторе ;) - последним
> ;)
В большинстве случаев так оно и надо. Ты же не хочешь постоянно задумываться в теле конструктора имеешь ты право обратиться к каким-либо полям-объектам предка. Сначала вызываешь конструкор предка, а потом уже свободно работаешь со всем "наследством".
Ну и та же ситуация с точностью до наоборот в деструкторе.
Ситуация с конструктором у TThread значительно отличается в этом смысле от стандартного случая.
Вызвав первым делом inherited Create(false), ты толжен отдавать себе отчет в том, что далее одновременно с оставшимся кодом конструктора УЖЕ выполняется метод Execute и, соответственно понимать к чему это может привести.
← →
Verg (2004-02-06 11:28) [9]
> когда я делал CreateSuspended=FALSE, то Execute иногда вызывалась
> с AV защитой памяти при обращении к адресу 0. Во всяком
> случае при отладке я на такое точно напарывался (иду по
> шагам в конструкторе (первым его оператором Inherited),
> а тут вдруг вылетает указанное AV среди кода Execute при
> обращении к несозданному (понятно, т.к. создается в конструкторе)
> объекту.
Вот вот. Эту ситуацию в лит-ре еще называют "гонками".
← →
panov (2004-02-06 11:35) [10]Интересная тема-)
Вопрос в связи с топиком.
Если создаются объекты в конструкторе, то в каком кодовом потоке они находятся после создания? -)
← →
Тимохов (2004-02-06 11:50) [11]
> Пусть для работы потока нужны какие-то объекты (невизуальные).
>
ИМХО стоит заметить, что com объекты тоже невизуальные.
Такой вопрос, о том, где создавать, может быть поставлен для com-объектов в полной мере - там это важно. Для обыкновенных объектов дельфи это не имеет значения - создавай, где хочешь, главное, про синхронизацию не забывай.
← →
KSergey (2004-02-06 11:52) [12]> [11] Тимохов © (06.02.04 11:50)
> Такой вопрос, о том, где создавать, может быть поставлен
> для com-объектов в полной мере - там это важно.
Так где? ;)
← →
Bel (2004-02-06 11:53) [13]> panov © (06.02.04 11:35) [10]
> Если создаются объекты в конструкторе, то в каком кодовом потоке они находятся после создания?
А разве объекты находятся в кодовом потоке? :))
← →
Тимохов (2004-02-06 11:56) [14]
> KSergey © (06.02.04 11:52) [12]
Что "Так где?".
Ты о чем сам то говорил - о простых объектах дельфи или о com-объеках?
Если о простых, то создавай где хочешь и работай как хочешь.
Если о com - надо учитывать потоковую модель com объекта. Хотя, если сервер внутренний, можно забить, используя свои методы синхронизации (типа крит. секций). Но указанный метод, хоть и работает, по словам авторов некоторых книг противоречит идеологии потоковых моделей.
← →
Sandman25 (2004-02-06 12:00) [15]С точки зрения идеалогии, если у каждого TThread свои копии объектов, то и создавать их надо в контексте данного TThread, ИМХО, то есть в Execute.
← →
pasha_golub (2004-02-06 12:02) [16]Есть еще метод AfterConstruction, который можно перекрыть и сделать все действия.
← →
Тимохов (2004-02-06 12:03) [17]ИМХО, думаю, что
> их надо
следует трактовать как "желательно". :)))
← →
Sandman25 (2004-02-06 12:06) [18][17] Тимохов © (06.02.04 12:03)
Естественно. В программировании очень редко именно "надо", всегда есть куча способов нарушить правило и сделать по-другому.
← →
Sandman25 (2004-02-06 12:06) [19]И не только способов, но и ситуаций, когда рекомендуется нарушить общую рекомендацию :)
← →
KSergey (2004-02-07 12:35) [20]> Тимохов © (06.02.04 11:56) [14]
Извиняюсь
Я говорил лишь об объектах дельфи. Более того - не связанных с объектами ОС (окнами, например и т.д.)
> pasha_golub © (06.02.04 12:02) [16]
> Есть еще метод AfterConstruction, который можно перекрыть
> и сделать все действия.
Можно, но что то меняет?
Вообще, если я ничего не путаю (дельфи нет, проверить не могу), сей виртуальный метод вызывается в конце конструктора TObject, а потому не ивжу разницы: перекрыть конструктор или AfterConstruction. Хотя и использую часто, т.к. не надо параметры гонять туда-сюда.
Если заблуждаюсь - направьте на истинный путь ;)
← →
Бином Ньютоныч (2004-02-08 16:26) [21]KSergey © (07.02.04 12:35) [20]
>не ивжу разницы: перекрыть конструктор или AfterConstruction
Есть один очень важный момент. Если конструкторе сгенерить исключение, то деструктор будет вызван, а вот AfterConstruction и BeforeDestruction - нет.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.02.17;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.019 c