Модераторы: Snowy, Poseidon, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Зависание приложения Delphi 
V
    Опции темы
Vlarim
Дата 12.3.2014, 07:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 21.8.2011

Репутация: нет
Всего: нет



Добрый день.

Помогите решить проблему зависания приложения.

Суть приложения:
Цикл каждые 3 мин
{
    - ClientSocket поочередно подключается к 5 железякам, опрашивает, парсит данные, заносит в 2 таблицы
    - idTelnet подключается к одному серверу, делает 8 запросов, парсит, заносит в другие 2 таблицы.
    - ServerSocket позволяет подключаться клиентам, после зарешения всех опросов (ClientSocket и idTelnet), данные из таблиц передаются подключенным клиентам (2-6 клиентов).
}
Все это работает стабильно в течении суток+-.
Потом окно перестает обновляться, реагировать на закрытие.

Process Explorer показывает 6 потоков:
- 4 с именем программы - Wait:UserRequest
- WS2_32.dll!SockAsyncTread - Wait:UserRequest
- kernel32.dll!BaseThreadStartThunk - Wait:WrLpcReceive

Если в каждую процедуру и функцию понатыкать логирование начала и конца, то лог заканчивается всегда на работе таймера. Данный таймер каждый раз сбрасывается после опросов и служит для читаемого отображения отсчета 3х минут (т.е. интервал в 180 сек показывает в виде mm:ss в поле Edit).
PM MAIL   Вверх
kami
Дата 12.3.2014, 08:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 6
Всего: 72



MadExcept + включение отладочной информации в помощь. При зависании создастся баг-репорт, содержащий полную информацию - что, в какой последовательности вызывалось и на какой строчке зависло.

Цитата(Vlarim @  12.3.2014,  07:15 Найти цитируемый пост)
Process Explorer показывает 6 потоков:

А что с хендлами и private bytes?

Добавлено через 2 минуты и 11 секунд
В дополнение:
Цитата(Vlarim @  12.3.2014,  07:15 Найти цитируемый пост)
ClientSocket поочередно подключается к 5 железякам, опрашивает, парсит данные

Случайно в ходе этого Application.ProcessMessages не используется?
PM MAIL WWW   Вверх
Vlarim
Дата 12.3.2014, 09:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 21.8.2011

Репутация: нет
Всего: нет



MadExcept + включение отладочной информации - сделал, придется подождать денек.

Application.ProcessMessages не совсем понятно куда добавлять.
ClientSocket работает в NonBlocking. Шлю комманду, полученные данные парсю.

Раньше не приходилось работать с отладкой, поэтому хендлы не просматривал, завтра как зависнет - гляну.


Присоединённый файл ( Кол-во скачиваний: 6 )
Присоединённый файл  perf.JPG 246,66 Kb
PM MAIL   Вверх
kami
Дата 12.3.2014, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 6
Всего: 72



Цитата(Vlarim @  12.3.2014,  09:15 Найти цитируемый пост)
Application.ProcessMessages не совсем понятно куда добавлять.

Никуда не надо, наоборот - от этого костыля, если он есть, надо избавляться.
Обычно его использование говорит о... о многом smile

Цитата(Vlarim @  12.3.2014,  09:15 Найти цитируемый пост)
MadExcept + включение отладочной информации - сделал, придется подождать денек.

меню Project => Madexcept settings => Enable Madexcept (или что-нибудь в этом духе, у меня 3.0, а они вроде как уже 4-ю версию выпустили) галочка поставлена?
Там же - check for frozen main thread включено?

Если да - тогда ждем багрепорт...

Это сообщение отредактировал(а) kami - 12.3.2014, 09:30
PM MAIL WWW   Вверх
Alexeis
Дата 12.3.2014, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 2
Всего: 459



Цитата(kami @  12.3.2014,  10:29 Найти цитируемый пост)
Обычно его использование говорит о... о многом 

  Неуместное использование говорит о многом. В случае когда используется функция WSAAsyncSelect для обработки уведомлений асинхронного сокета в главном потоке, то Application.ProcessMessages как раз таки будет уместно бороться с зависаниями типа дедлока (хотя эффективнее использовать MsgWaitForMultipleObjects с таймаутом). Но в данном случае, ИМХО ситуация больше похожа, на то что одна из сторон аварийно закрыла соединение, а вторая продолжает думать, что соединение еще живое, шлет данные в пустоту и ждет ответа. В этом случае нужно проверять результаты функций recv / send логировать в случае неуспеха.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Vlarim
Дата 13.3.2014, 05:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 21.8.2011

Репутация: нет
Всего: нет



Bug report появился еще до зависания приложения, но нет кнопочки Save bug report, извратился картинкой в приложении, добавил кнопку, в следующий раз можно будет сохранить.

Application.ProcessMessages - все же используется в функции для работы с телнетом.

Ниже пример функции. У меня малость изменено, пока отлаживал подключение к телнет скидывал все данные в Memo,
и в этой функции вместо TelnetBuf - тот же Memo.
 
Код

function WaitString(const aStr: string): string; 
var p: integer;
 begin 
  TimerWait.Enabled := true; 
  try 
    repeat 
      Application.ProcessMessages; 
      sleep(100); 
      p := pos(aStr, TelnetBuf); 
    until not IdTelnet.Connected or (p > 0); 
    if p > 0 then begin 
      Result := copy(TelnetBuf, 1, p + length(aStr)); 
      Delete(TelnetBuf, 1, p + length(aStr)); 
    end else 
      Result := ''; 
  finally 
    TimerWait.Enabled := false; 
  end; 
end;


check for frozen main thread  - не стояла, как зависнет запущу заново уже с этой галкой.

Это сообщение отредактировал(а) Vlarim - 13.3.2014, 07:38

Присоединённый файл ( Кол-во скачиваний: 9 )
Присоединённый файл  Безымянный.JPG 557,27 Kb
PM MAIL   Вверх
Vlarim
Дата 19.3.2014, 04:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 21.8.2011

Репутация: нет
Всего: нет



Как то в этот раз довольно долго проработала.

Зависла.

В приложении репорт с "The application seems to be frozen"

Пожалуйста подскажите как выяснить причину. 
Полгода уже, сил уже нет.

Присоединённый файл ( Кол-во скачиваний: 9 )
Присоединённый файл  bugreport.txt 18,49 Kb
PM MAIL   Вверх
kami
Дата 19.3.2014, 08:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 6
Всего: 72



Цитата

00517b35 +c9d CheckBSC.exe Main      2047  +92 TForm1.SendData

Это куда senddata? в клиентский сокет или одно из подключений серверного?

Это сообщение отредактировал(а) kami - 19.3.2014, 08:10
PM MAIL WWW   Вверх
Vlarim
Дата 19.3.2014, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 21.8.2011

Репутация: нет
Всего: нет



В этой процедуре происходит пробегание по строкам таблиц и отправка данных подключенным клиентам.
PM MAIL   Вверх
kami
Дата 19.3.2014, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 6
Всего: 72



Смущает одно: в контексте главного потока производится попытка отправки данных в сокет, "принадлежащий" другому потоку (наследник TServerClientThread - TServerThread, если я правильно читаю). Я же ничего не путаю - судя по багрепорту, сервер работает в stThreadBlocking?
Имхо, именно на этом и возникает дедлок. Отправляй данные в контексте своего TServerThread и будет щасте.
PM MAIL WWW   Вверх
Vlarim
Дата 19.3.2014, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 21.8.2011

Репутация: нет
Всего: нет



Т.е в контексте TServerThread добавляю что то вроде:
Код

procedure TServerThread.SendAllClients(var aData: PData);
var
  i, j, Clients: Word;
begin
  Clients:= ServerSocket.Socket.ActiveThreads - 1;
  for j:=0 to Clients do
     ServerSocket.Socket.Connections[j].SendBuf(aData^, SizeOf(aData^))
end;

Вопрос - как в главном потоке вызвать эту процедуру?

С примерами туговато по этой части.


Это сообщение отредактировал(а) Vlarim - 19.3.2014, 12:42
PM MAIL   Вверх
kami
Дата 19.3.2014, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 6
Всего: 72



Стоп-стоп. Я мог сделать неверное предположение, т.к. имею перед глазами только багрепорт, а не исходники.
Кто такой TServerThread? От чего он наследуется? Я правильно понял, что 
Код
TServerThread = class(TServerClientThread)
?

В любом случае - приведенный в TServerThread.SendAllClients код нельзя считать правильным. У каждого соединения - свой поток. Каждое соединение должно отправлять и принимать данные в контексте своего потока. А в этом методе производится попытка отправить данные всем клиентам из одного потока. Так низзя.

За сим - умолкаю, так как с stThreadBlocking не работал, не работаю и не буду, а давать вредные советы - не хочу smile




Это сообщение отредактировал(а) kami - 19.3.2014, 12:57
PM MAIL WWW   Вверх
Vlarim
Дата 19.3.2014, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 21.8.2011

Репутация: нет
Всего: нет



Да и на этом спасибо.
Цитата

Я правильно понял, что 

Правильнее некуда.

Понятно, что из своего потока нужно отправлять сообщение только своему клиенту.
Но сколько примеров не видел, все отправляют сообщения из главного потока.

Буду продолжать поиски рабочих примеров.
PM MAIL   Вверх
kami
Дата 19.3.2014, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 6
Всего: 72



Пример, правда - в не-блокирующем режиме
Код заточен под работу из-под любого потока. Выложенная реализация, не лишена недостатков (в частности, в виде утечек памяти).
Смотреть метод TDataTransferServer.SendOutStreamToSingleConnection, он асинхронно (в нужном потоке) вызывает событие TDataTransferServer.OnWrite.

Общий принцип, реализованный в этом примере - у каждого соединения есть свои буферы на прием и на передачу. Попытка отправить данные - это всего-навсего добавление информации в буфер. А потом - вызов реального "отправщика", в контексте потока, владеющего сокетом.
PM MAIL WWW   Вверх
Vlarim
Дата 24.3.2014, 07:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 21.8.2011

Репутация: нет
Всего: нет



Спасибо за пример.
Попробую разобраться.
Сразу возник вопросик, каким образом можно отправить записи.
Т.е. я отправляю

Код

TData = packed record
  fTable: Byte;
  fCol1: String[10];
  ...
  fCol10: String[10];
end;

Скорее всего надо функцию, которая будет приводить записи к String, а на стороне клиента обратно.


Это сообщение отредактировал(а) Vlarim - 24.3.2014, 07:24
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0989 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.