![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Работа с одной переменной в нескольких потоках. [D6, Win95/98, WinME, Win2k, WinXP]
SergP © (2005-12-11 20:09:00)Мне нужно изменить значение переменной ShortDateFormat, затем выполнить некоторые действия, после чего восстановить значение этой переменной.
SaveSDF:=ShortDateFormat;
ShortDateFormat:=....;
// Некоторые действия
ShortDateFormat:=SaveSDF;
Проблема в том что в приложении работает несколько потоков в которых, также как и в основном потоке используется данная конструкция. И поэтому в процессе выполнения данного кода в одном потоке не должны выполняться другие потоки.
Пока проблем не возникало. Но есть предчуствия, что это нехорошо. Но хочу подстраховаться.
Как сделать то что мне нужно?
Alexander Panov (2005-12-12 21:59:00) [1]Leonid Troyanovsky © (12.12.05 18:44) [16]
Думаю, что если алгоритм в потоке непрозрачный, т.е. используются дополнительные компоненты, например, из пакета Indy, то нельзя быть уверенным, что в этих компонентах нет обращения к глобальным переменным там, где нет защиты от одновременного чтения/записи. В этом случае получаем практически неуловимые ошибки при преобразовании дат в разных потоках.
Я это имею ввиду.
Leonid Troyanovsky (2005-12-12 18:44:00) [2]
> Alexander Panov © (12.12.05 18:33) [15]
> Каждую функцию не защитишь, только если всю процедуру потока
> поместить в Synchronize.
Всю - может быть излишне, а вот обращение к глобальным переменным
(заведомо принадлежащих первичному потоку) - всенепременно.
Т.е., само обращение достаточно универсально: сохраняем исходные,
делаем преобразование, восстанавливаем в finallly.
--
Regards, LVT.
Alexander Panov (2005-12-12 18:33:00) [3]Leonid Troyanovsky © (12.12.05 13:47) [13]
Лучше, все же Synchronize. Бо, куда (и как) совать секцию в
первичном потоке - это еще искать надо.
Сдается мне, что ни один вариант не поможет, кроме как конвертация вручную, так как обращение к глобальным переменным выполняется во многих компонентах и функциях внутри VCL. Каждую функцию не защитишь, только если всю процедуру потока поместить в Synchronize.
evvcom (2005-12-12 14:49:00) [4]
> Alexander Panov © (12.12.05 10:46) [9]
> evvcom © (12.12.05 10:04) [8]
>
> Что такое TFormatSettings и где про него почитать?
В хелпе вестимо. Единственно на что я не обратил внимания - это на версию дельфи автора. Да, в Д7 есть, а в Д6 вроде как нет.
Leonid Troyanovsky (2005-12-12 13:47:00) [5]
> Игорь Шевченко © (12.12.05 13:05) [12]
> Ввести критическую секцию, обращаться к ней во всех потоках
> перед выполнением указанного кода. Классика.
Лучше, все же Synchronize. Бо, куда (и как) совать секцию в
первичном потоке - это еще искать надо.
--
Regards, LVT.
Игорь Шевченко (2005-12-12 13:05:00) [6]
> Как сделать то что мне нужно?
Ввести критическую секцию, обращаться к ней во всех потоках перед выполнением указанного кода. Классика.
Rouse_ (2005-12-12 12:35:00) [7]а может проще работать через threadvar?
umbra (2005-12-12 10:48:00) [8]TFormatSettings появился только в Д7. В Д6 такого нет
Alexander Panov (2005-12-12 10:46:00) [9]evvcom © (12.12.05 10:04) [8]
Что такое TFormatSettings и где про него почитать?
evvcom (2005-12-12 10:04:00) [10]
> SergP ©
Тебе ж сказали про TFormatSettings, а ты проигнорировал. И не нужны никакие переприсваивания глобальных переменных и синхронизация потоков, которая вызовет довольно ресурсоемкое дополнительное ненужное переключение потоков.
Alexander Panov (2005-12-11 23:17:00) [11]>SergP © (11.12.05 22:05) [5]
Я бы не стал закладываться на то, что в дополнительных потоках не используются глобальные переменные и, во избежание проблем, конвертацию даты проводил вруную, без использования функций, использующих эти переменные.
DrPass (2005-12-11 22:52:00) [12]
> Это только в одном случае - если используется синхронизация
> методом TThread.Synchronize
Так он же так и делает
SergP (2005-12-11 22:05:00) [13]
> >SergP © (11.12.05 20:09)
>
> Может быть, стоит пересмотреть логику приложения?
У меня в дополнительных потоках закачивается контент по http и https с сервера (через WinInet) и сразу же происходит их парсинг (а там в контенте встречаются даты в разных форматах). А в основном потоке нужно делать TdateTime --> string в требуемом формате.
Но в принципе я понял: я могу обрабатывать полученый контент в основном потоке, и тогда проблемы исчезнут.
Alexander Panov (2005-12-11 21:39:00) [14]DrPass © (11.12.05 21:32) [3]
А с ним ничего и не надо - Synchronize выполняет метод в его контексте, так что он гарантированно будет синхронизирован.
Это только в одном случае - если используется синхронизация методом TThread.Synchronize.
В остальных случаях сделать синхронизацию не удастся, так как эту переменную могут использовать и многочисленные компоненты, объекты, а также функции, спрятанные в глубинах VCL.
>SergP © (11.12.05 20:09)
Может быть, стоит пересмотреть логику приложения?
DrPass (2005-12-11 21:32:00) [15]А с ним ничего и не надо - Synchronize выполняет метод в его контексте, так что он гарантированно будет синхронизирован.
SergP (2005-12-11 21:12:00) [16]
> DrPass © (11.12.05 20:49) [1]
Через TThread...
Вобщем насчет дополнительных потоков понятно. (Synchronize).
А как быть с основным потоком?
DrPass (2005-12-11 20:49:00) [17]Если потоки реализованы через TThread, проще всего поместить это в отдельный метод и вызывать его через Synchronize. Если потоки реализованы классически, через CreateThread, то тогда нужно синхронизировать через критические секции. В Delphi 7+ можно вообще обойтись без этого, там существует возможность "локального" изменения форматов с помощью TFormatSettings, не задействуя глобальные переменные.