|
|
|
Gradov |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 31.10.2006 Репутация: 2 Всего: 3 |
Привет всем. Делаю приложение, в котором есть несколько потоков, работа с сетью и БД. Есть одна заморочка, которую никак не могу разрешить. Программа работает, но иногда виснет. Т.е. "иногда" - это значит иногда она может нормально отработать, а иногда зависнуть, т.е. непредсказуемо. Поймать где именно мне не удается. Проверил все, что только можно проверить и остановился на том, что это конфликты при многопотоковом доступе. В связи с этим возникает вопрос о том как правильно разрулить конфликты многопотокового доступа в VCL-приложении.
В справке к компоненту TThread есть замечание: Most methods that access a VCL object and update a form must only be called from within the main VCL thread or use a synchronization object such as TMultiReadExclusiveWriteSynchronizer. Означает ли это, что любое обращение не из VCL потока к компонентам надо делать через объекты синхронизации? Т.е. установка свойств, например, Button1->Enabled, Label1->Caption и т.д., а также чтение и запись свойств таких компонентов как TTable, TQuery тоже надо обязательно через synchronize? Это ж тогда получатся один VCL-thread будет работать и все преимущество многопоточности потеряется!?
Вот такое простое обращение к табличке надо ли оформлять через Synchronize не в VCL-потоке? Спрашиваю потому как это добавляет дополнительного гемороя, из-за того что метод Synchronize должен быть void-ным с обеих сторон. Т.е. вернуть значение нельзя, нужно будет использовать доп. переменную. PS: когда код более 10000 сторок вот таких маленькие фрагменты задолбаешься переделывать. Это сообщение отредактировал(а) Gradov - 24.3.2009, 16:54 |
|||
|
||||
mrbrooks |
|
|||
трололомен Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 167 Всего: 306 |
Gradov, рекомендуется любую работу с VCL классом в потоке TThread производить через метод Synchronize.
|
|||
|
||||
Gradov |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 31.10.2006 Репутация: 2 Всего: 3 |
Что даже условие
|
|||
|
||||
mrbrooks |
|
|||
трололомен Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 167 Всего: 306 |
Gradov, если у тебя именно на цикле подвисает то не забудь сделать так:
|
|||
|
||||
Alca |
|
|||
Эксперт Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 25 Всего: 50 |
Критические секции пробывал?
|
|||
|
||||
Gradov |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 31.10.2006 Репутация: 2 Всего: 3 |
Они не помогут в разрешении конфликтов доступа к VCL-компонентам. Поскольку насколько мне изветсно библиотека VCL-непотокобезопасна. Т.е. если я, например, код обращения к таблице оформлю через Critical Sections, то это будет одностороннее решение.
Но это все равно не решение. Потому как я много других вариантов приведу, которые я тоже не знаю делать через Synchronize или нет, например Button2->Enabled=false, Label5->Caption="Name45", Query4->SQL->Clear() и т.д. |
|||
|
||||
Alca |
|
|||
Эксперт Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 25 Всего: 50 |
Эт как? |
|||
|
||||
Gradov |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 31.10.2006 Репутация: 2 Всего: 3 |
||||
|
||||
mrbrooks |
|
|||
трололомен Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 167 Всего: 306 |
Обоснуй. Приведи. Начнем с того что тот код который я тебе показал ни какого отношения к потокам не имеет. Это стандартная навигация по таблице, при чем при большом количестве данных. Судя по тому, что ты здесь написал, читай литературу по базам данных и потокам - прежде чем поучать других, что помогает, а что нет. зы. Критические секции здесь действительно ни к чему. |
|||
|
||||
Gradov |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 31.10.2006 Репутация: 2 Всего: 3 |
Да никого я вроде бы и не поучал... Ну так а я тебя что просил мне показывать навигацию по таблице, при большом количестве данных?? Вопрос конкретно был задан: обращение на чтение к VCL-компонентам типа while(!Table1->Eof) нужно через synchronize делать не в VCL-потоке или нет - не будет при такои использовании конфликтов? |
|||
|
||||
Alca |
|
||||
Эксперт Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 25 Всего: 50 |
Исходник Synchronize:
Добавлено через 3 минуты и 57 секунд Работа с потоками в Delphi: так ли страшен чёрт, как его малюют? Это сообщение отредактировал(а) Alca - 24.3.2009, 18:47 |
||||
|
|||||
Gradov |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 31.10.2006 Репутация: 2 Всего: 3 |
Alca, дело в том что критические секции не помогут при разрешении конфликтов доступа к VCL-компонентам. Я же не влезу в код VCL и не смогу вставить туда свою критическую секцию, согласен? Вот поэтому я и говорил об одностороннем решении.
Добавлено @ 19:20 Вот и ты ссылку удачно привел. Но не всё так просто. Казалось бы - пишем любой код внутри метода Execute и всё, а нет, потоки имеют одно неприятное свойство - они ничего не знают друг о друге. И что такого? - спросите вы. А вот что: допустим, вы пытаетесь из другого потока изменить свойство какого-нибудь компонента на форме. Как известно, VCL однопоточна, весь код внутри приложения выполняется последовательно. Допустим, в процессе работы изменились какие-то данные внутри классов VCL, система отбирает время у основного потока, передаёт по кругу остальным потокам и возвращает обратно, при этом выполнение кода продолжается с того места, где приостановилось. Если мы из своего потока что-то меняем, к примеру, на форме, задействуется много механизмов внутри VCL (напомню, выполнение основного потока пока "приостановлено"), соответственно за это время успеют измениться какие-либо данные. И тут вдруг время снова отдаётся основному потоку, он спокойно продолжает своё выполнение, но данные уже изменены! К чему это может привести - предугадать нельзя. Вы можете проверить это тысячу раз, и ничего не произойдёт, а на тысяча первый программа рухнет. - Юрий Балыкин. Это сообщение отредактировал(а) Gradov - 24.3.2009, 19:32 |
|||
|
||||
mrbrooks |
|
||||
трололомен Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 167 Всего: 306 |
Вообще-то нет ответ уже был:
Что тут еще добавить? |
||||
|
|||||
dumb |
|
|||
sceloglauxalbifacies Профиль Группа: Экс. модератор Сообщений: 2929 Регистрация: 16.6.2006 Репутация: 32 Всего: 158 |
Gradov,
все визуальные компоненты можно считать небезопасными, а для не визуальных надо конкретно выяснять. например, TTimer не визуален, но и не безопасен из-за используемой AllocateHWnd. в твоем же случае, судя по всему, проблема в том, что для Table не выделена отдельная сессия. при работе с BDE правило такое: для каждого доп.потока - своя сессия, к которой следует привязывать компоненты, используемые в этом потоке. ну и, конечно, с этой Table не стоит напрямую связывать компоненты отображения. |
|||
|
||||
Gradov |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 124 Регистрация: 31.10.2006 Репутация: 2 Всего: 3 |
В общем лучше я так понял перестраховаться и всё загнать в synchronize.
dumb, я использую разные компоненты TTable для каждого потока. Насколько мне известно каждый новый TTable имеет свою сессию. Т.е. лишний расход памяти на новый компонент тоже может быть выходом, верно? |
|||
|
||||
Правила форума "С++ Builder" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C++ Builder | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |