![]() |
|
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]()
|
|
| Ibragim |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
И снова вопрос...
Собственно Subj. Наверняка где-то есть, но потраченный час на поиск не принес успеха, решилс спросить. Реализована ли защита переменных от одновременного доступа в TThread средствами самого TThread? Или нужно самому реализовавать? Есть вероятность чтения переменной а одновременно разными потоками. Можно ли делать так
или нужно так
Спасибо за ответ на наверняка уже звучавший вопрос. |
||||
|
|||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 26 Всего: 146 |
не понял как , но лучше имхо перестаховатся и делать через синхронизацию потоков, или как здесь через критические секции -------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| Sansa |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 18.10.2006 Где: Королев Репутация: 3 Всего: 6 |
Чтение переменной разными потоками не приведет к коллизиям. Главное чтоп не было одновременной записи
--------------------
- Здравствуйте, я Ваш патологоанатом |
|||
|
||||
| Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 192 Всего: 484 |
Переменная a у каждого треда будет своя собственная.
Никаких коллизий не будет, если только ты не попытаешься обратиться к переменной а одного треда из другого прямым указанием. |
|||
|
||||
| Ibragim |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
Snowy, Это я и имел в виду, когда писал "Есть вероятность чтения переменной а одновременно разными потоками". То есть другие потоки, положим TB = class(TThread), будут читать переменную у этого объекта (у ОДНОГО объекта класса TThread), может случиться что и одновременно.
Sansa, а если один читает а другой пишет? |
|||
|
||||
| Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 192 Всего: 484 |
Тогда защищать обязательно.
|
|||
|
||||
| Sansa |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 18.10.2006 Где: Королев Репутация: 3 Всего: 6 |
Ibragim, че-та я сегодня рассеяный немного. Не обратил внимание, что это член класса. Мой ответ применим к глобальной переменной. И если один пишет, а другой читает (глобальную переменную или член класса объявленного вне TThread'ов), то тоже коллизий не произойдет. Но если один ВСЕГДА ТОЛЬКО ПИШЕТ, а второй ВСЕГДА ТОЛЬКО ЧИТАЕТ
--------------------
- Здравствуйте, я Ваш патологоанатом |
|||
|
||||
| Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 192 Всего: 484 |
Sansa, нельзя так.
Ошибок не будет, но будет вероятность получения неактуальных данных. То есть мы получим устаревшее значение. Один тред возьмёт это значение, второй его изменит, а первый продолжит работать со старым значением, не подозревая, что оно уже неверное. |
|||
|
||||
| Ibragim |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
Гуд, общая идея понятна. Мнение - защищать. Так и будем делать. Всем спасибо, тема закрыта.
PS Тля, у меня штук пятьдесят таких переменных! Счас copy-paste все переделать в property и сделать на них CriticalSection's - бррр, ну пошел работать. |
|||
|
||||
| Sansa |
|
||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 18.10.2006 Где: Королев Репутация: 3 Всего: 6 |
Ibragim, скачай JCL и загляни в модуль JclSynch.pas. Там найдешь много полезных функций именно по локам, например:
И ничего копи-пастить не надо. Snowy, простой блокировкой от неактуальности в асинхронных процессах не избавишься, все зависит от задачи. Если выполняется простое действие типа
Если надо твердо определять актуальность данных, то необходимы более сложные алгоритмы. Например, как в OPC используются дополнительные поля Timestamp (когда изменилось) и Quality (не было ли ошибок при пересчете). Это сообщение отредактировал(а) Sansa - 19.12.2006, 16:21 --------------------
- Здравствуйте, я Ваш патологоанатом |
||||||
|
|||||||
| Snowy |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 192 Всего: 484 |
Это только кажется простоым.
На самом деле всё далеко не так просто. Вспомни хотя бы про interlocked. Они не спроста придуманы Например, наша переменная - это счётчик. Мы хотим сделать:
Опять же пример - у нас счётчик. Мы должны к нему добавить еденичку. По приведённому выше примеру видно, что в результате мы прибавим одну еденичку, а не две. И эта ошибка будет нестабильной, проявляясь в то время, когда не надо, а не когда мы её ловим |
||||
|
|||||
| Sansa |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 18.10.2006 Где: Королев Репутация: 3 Всего: 6 |
Я особо выделил, что для того, чтобы не надо было использовать локи, переменная должна изменяться в одном месте, а у тебя в примере получается в 2-х. Если мы прибавляем 1 в одном потоке, а во втором в это время читаем эту переменную, то все казусы - это то, что мы не будем точно знать увеличенное или нет у нас взято значение вторым потоком. Но локи тут не помогут. Мы будем лишь твердо уверены в том, что мы взяли переменную либо до выполнения этой строки (c:= c+1) либо после, но никак не во время. Это мало что дает на практике.
Яркий пример того, что я имел в виду: Есть поток, который 100 раз в секунду получает значение (скажем температуры) с СОМ порта, и записывает ее в глобальную переменную. Второй поток с частотой того же порядка (скажем 90 Гц) читает эту переменную и выполняет какие-то операции в зависимости от ее значения. И есть 3-й поток, который раз в секунду читает это же значение и отображает его на экране. Без локов программа будет работать даже эффективнее, так как при их использовании и критичных ко времени алгоритмах (или высоких частотах опроса переменной) могут возникать таймауты, так как потоки будут тратить время на ожидание друг друга. --------------------
- Здравствуйте, я Ваш патологоанатом |
|||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 26 Всего: 146 |
данный пример , имхо проще сделать используя сообщения безопаснее! -------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| Sansa |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 173 Регистрация: 18.10.2006 Где: Королев Репутация: 3 Всего: 6 |
Согласен. И с точки зрения ООП - грамотнее. Но это надо мутить контроллер, который будет раздавать всем зарегистрированым "потребителям сего значения" сообщения о его изменении, причем с указанным для каждого из них таймаутом.
--------------------
- Здравствуйте, я Ваш патологоанатом |
|||
|
||||
| Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 192 Всего: 484 |
Пример всего дишь для того, чтобы показать, что защищать надо.
Можно придумывать ситуации, когда это не очень важно или не так страшно. Но лучше защищать всегда. |
|||
|
||||
![]()
|
| Правила форума "Delphi: Общие вопросы" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |