![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| TGrey |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 294 Регистрация: 1.12.2007 Репутация: нет Всего: 1 |
Здравствуйте, делаем с другом авторизатор для чата. Отдельные модули писали в VC после чего я сделал интерфейс в Борланде и интегрировал все части. У меня работает все хорошо, ну относительной той части, что должно работать, а вот у друга сразу же возникают проблемы.
1)Для вывода текста используем CppWebBrowser у меня все работает отлично у друга при вызове функции CppWebBrowser::Refresh() программа крашится. 2)Используем Сокеты для приема данных, как задержку я установил Sleep. Но поскольку он усыпляет основной поток, я создаю другой и он уже ловит сообщения. У меня по прежнему все хорошо, у друга, Слип действует на оба потока. Причем когда у него была предыдущая версия с неверным алгоритмом обработки строк Слип там действовал, как нужно, после того, как я переделал алгоритм, который никаким образом не относится к потокам и скинул новую версию другу, начался этот прикол со Слипом(только у него). Попробовал скинуть готовый проект при запуске пишет обращение к запрещенной памяти(я полагаю Refresh() в браузере) и программа ложится. Кто знает как с этим боротся, подскажите пожалуйста. |
|||
|
||||
| GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
TGrey, код покажи
|
|||
|
||||
| TGrey |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 294 Регистрация: 1.12.2007 Репутация: нет Всего: 1 |
Кода очень много... Вот та часть, где основная проблема
Вот тут Рефреш у друга вызывает краш, а Слипы усыпляют не только свой поток. Сейчас попробовал перевести со Слипов в Таймер, но Сокет блокирующий и поэтому пока он ждет данных программа тоже висит. Думаю сейчас еще попробовать вернуть все в поток, но вместо Слипов проверять fd_set на чтение сокетом инфы. Поток создается нажатием на кнопку
|
||||
|
|||||
| TGrey |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 294 Регистрация: 1.12.2007 Репутация: нет Всего: 1 |
Блин..... Перейдя на select и убрав все Слипы, обнаружил гадость(( У друга все в том же месте главное окно висит. Если там всунуть МесседжБокс то пока он открыт окном можно манипулировать и просмотреть данные, но как только жму ОК на нем программа снова переходит в затупленный режим.
Остается вариант, что блокирующий сокеты просто напросто блочат окно пока ждут инфу. Но интересно, как они это делают из другого потока?! --------------------------------------------- Теперь еще лучше, поменял режим на неблокирующий читаю инфу и темнемение программа всеравно виснет, хоть и не постоянно но 1 раз в 5 сек точно. Новый код
Это сообщение отредактировал(а) TGrey - 4.10.2009, 20:29 |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
1) Очень странные if'ы в начале Connector::CLogin - рекомендуется им приделать какое нибудь тело (хотя бы пустое - в виде ;). Пока у них телом выступает второй if и Sleep(7000)
2) Вызывать VCL объекты (ChatWindow->wb->Refresh();) из тела thread'а нельзя - VCL на это не расчитанна. Пользуйтесь TThread и его методом Synchronize |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Согласен с xvr.
TGrey, описываемое тобой явление очень похоже на случай "гонки" ("соревнование" или "race condition"), когда идет одновременная работа с одними и теми же данными из разных потоков без синхронизации. |
|||
|
||||
| TGrey |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 294 Регистрация: 1.12.2007 Репутация: нет Всего: 1 |
Ах да, if. Переносил с консоли вывод закоментил тело забыл дописать, но по сути это не должно быть ключевой проблемой.
Спасибо за подсказку я не знал, что обычные потоки не подходят для VCL. Сейчас попробую с TThread. И какую же функцию пихать в Синхронизацию? Как видите я все запихал в класс и что тогда синхронизировать и как это лучше всего сделать? И тогда такой вопрос, почему же у меня все замечательно работает? И кстати класс у меня с VC. То есть для синхронизации нужно переписать его в BCB и тогда возможно будет Синхронизировать его функции. Так? ------------------------- Так-с совсем забыл про тестовые выводы данных из потока. Закоментил их + Рефреш обрабатываю таймером в зависимости от значения булевой переменной и теперь работает без глюков.(Поток оставил старый) Пока все хорошо. Возникнут проблемы вернусь спрошу. Спасибо. Это сообщение отредактировал(а) TGrey - 5.10.2009, 21:43 |
|||
|
||||
| xvr |
|
||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Любую функцию. Все общение с VCL объектами можно делать ТОЛЬКО из такой функции. Т.е. схема действия такова
|
||||||||
|
|||||||||
| TGrey |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 294 Регистрация: 1.12.2007 Репутация: нет Всего: 1 |
Лучше через секцию) Т.к. с атомарными операциями дела я не имел.
С булевой работаю так: Если сообщение пришло и нужно обновить чат, то ставлю ее в true Таймер крутится проверяя ее значение, если оно true, то в теле таймера происходит Рефреш и переменная сбрасывается. Будет ли достаточно в этот момент, когда переменная сбрасывается занести ее в Критическую секцию, это не позволит тому потоку продолжать принимать сообщения и выставлять переменную заново? |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Нет, недостаточно. В секцию надо заключать установку этой переменной из потока, и проверку со сбросом (ОБЯЗАТЕЛЬНО вместе) из основной программы |
|||
|
||||
| TGrey |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 294 Регистрация: 1.12.2007 Репутация: нет Всего: 1 |
То есть когда я получаю данные и нужно установить переменную, я эту часть пихаю в секцию(это внутри класса), а в Таймере просто пишу проверку и сброс? Или я не понял?
|
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Обе части, и в Таймере тоже. Секция предназначена для защиты доступа к общему ресурсу из РАЗНЫХ мест (потоков). Т.е. их (мест) должно быть как минимум 2 |
|||
|
||||
| TGrey |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 294 Регистрация: 1.12.2007 Репутация: нет Всего: 1 |
Хорошо. Еще раз спасибо
|
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |