Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.10.2013, 10:46   #1
Son
Пользователь
 
Аватар для Son
 
Регистрация: 24.11.2008
Сообщений: 76
По умолчанию Потоки. Закрываются все потоки при ошибке в одном.

Здравствуйте. Я создаю несколько однотипных потоков для чтения устройств по COM портам с помощью процедуры BeginThread.
Вот примерный вид функции потока:
Код:
procedure ThreadModbusRead(Param : pointer);
var MB : TModbus;
begin
  MD:=TModbus.Create;
  WriteLog('Запущен');
  if not MB.Connect then
  begin
    WriteLog('Ошибка подключения');
    EndThread(0);
  end;
  while flExit do
  begin
    MB.ReadHoldinRegister
  end;
  WriteLog('Остановлен');
end;
Если один поток, то все ОК. Если пускаю 2 потока и они работают, то тоже ОК. Но если один из потоков не может подключиться, то вроде останавливаются оба потока. Возможно я не так выхожу из потока и функция выходит во всех потоках?
Лучше сдохнуть, чем жить с иглой в яйце (Кащей Бессмертный)
Son вне форума Ответить с цитированием
Старый 28.10.2013, 12:10   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Цитата:
вроде останавливаются оба потока
Ну так они же к одному и тому же устройству, может потому что само устройство молчит, потому и все потоки не могут работать?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 28.10.2013, 12:55   #3
Son
Пользователь
 
Аватар для Son
 
Регистрация: 24.11.2008
Сообщений: 76
По умолчанию

устройства разные. если к одному подключился, а к другому нет, то оба потока останавливается
Лучше сдохнуть, чем жить с иглой в яйце (Кащей Бессмертный)
Son вне форума Ответить с цитированием
Старый 28.10.2013, 13:55   #4
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

Код:
procedure ThreadModbusRead(Param : pointer);
var MB : TModbus;
begin
  try
    MD:=TModbus.Create;
    try
      WriteLog('Запущен');
      if not MB.Connect then
      begin
        WriteLog('Ошибка подключения');
        Abort;
      end;
      while flExit do
      begin
        MB.ReadHoldinRegister
      end;
      WriteLog('Остановлен');
    finally
      MD.Free;
    end;
  except
    on e:exception do
      WriteLog(e.message);
  end;
  EndThread(0);
end;
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 28.10.2013, 14:01   #5
Son
Пользователь
 
Аватар для Son
 
Регистрация: 24.11.2008
Сообщений: 76
По умолчанию

Про исключения я не подумал. Спасибо. Попробую применить у себя. А процедура Abort что делает?
Лучше сдохнуть, чем жить с иглой в яйце (Кащей Бессмертный)
Son вне форума Ответить с цитированием
Старый 28.10.2013, 15:13   #6
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

Abort - "мягкое" исключение прерывающее работу процедуры
а ты вызывал EndThread(0) и продолжал работу while flExit do
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 31.10.2013, 10:37   #7
Son
Пользователь
 
Аватар для Son
 
Регистрация: 24.11.2008
Сообщений: 76
По умолчанию

Попробовал, но к сожалению та же ерунда. Вот код:
Код:
procedure ModbusRead(Parameter : Pointer);
var MB : TModbus;
    idDev : integer;
    fExit : boolean;
begin
  //
  try
    SynchCS.Enter;
    idDev:=integer(Parameter);
    Form1.RichEdit1.Lines.Add(inttostr(idDev)+' Старт.');
    SynchCS.Leave;
    try
      SynchCS.Enter;
      MB := TModbus.Create;
      if not MB.Connect(Get_COMPortNumber(arDevice[idDev].PortName),
                        Get_COMBaudRate(arDevice[idDev].BaudRate),
                        Get_COMParity(arDevice[idDev].Parity),
                        Get_COMDataBits(arDevice[idDev].DataBits),
                        Get_COMStopBits(arDevice[idDev].StopBits)) then
      begin
        Form1.RichEdit1.Lines.Add(inttostr(idDev)+' Ошибка подключения.');
        Form1.tbDevice.Cells[2,idDev+1]:='Ошибка';
        Abort;
      end;
      Form1.tbDevice.Cells[2,idDev+1]:='Запущен';
      SynchCS.Leave;
      fExit:=false;
      while not fExit do
      begin
        sleep(500);
        SynchCS.Enter;
        fExit:=blFlag_Exit;
        SynchCS.Leave;
      end;
      
    finally
      MB.Free;
    end;
    Form1.tbDevice.Cells[2,idDev+1]:='Остановлен';
  except
    on e:exception do
    begin
      SynchCS.Enter;
      Form1.RichEdit1.Lines.Add(inttostr(idDev)+' '+e.Message);
      Form1.tbDevice.Cells[2,idDev+1]:='Ошибка';
      SynchCS.Leave;
    end;
  end;
  EndThread(0);
end;
В сообщениях остается такой лог:

0 Старт.
1 Старт.
0 Ошибка подключения.
0 Operation aborted
Лучше сдохнуть, чем жить с иглой в яйце (Кащей Бессмертный)
Son вне форума Ответить с цитированием
Старый 31.10.2013, 17:44   #8
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

Нельзя из потока лезть на форму, и всякие SynchCS не заменят встроенного Synchronize!
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 31.10.2013, 18:41   #9
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Критические секции для другого нужны. Например, когда несколько потоков используют какой-то общий ресурс. Тогда они все должны входить в одну и ту же CS при обращениях к нему. А с формой так не получится. Используйте наследника TThread и Synchronize.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 31.10.2013, 21:51   #10
Son
Пользователь
 
Аватар для Son
 
Регистрация: 24.11.2008
Сообщений: 76
По умолчанию

Хотел уйти от стандартных реализаций потоков в Delphi, поскольку слышал об их глючности. Пока сделал один поток с опросов всех устройств.
Лучше сдохнуть, чем жить с иглой в яйце (Кащей Бессмертный)
Son вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как остановить все потоки DAN1L C# (си шарп) 1 13.12.2012 12:09
Все еще потоки... pinkiller Общие вопросы C/C++ 7 08.01.2012 15:21
Потоки: неверный дескриптор(6) при создании потока [MoNAMur] Общие вопросы Delphi 4 08.11.2011 12:05
Удалить все потоки при закрытии, предварительно не создавав массив их хендлов? TwiX Общие вопросы Delphi 4 18.02.2010 22:54
Не удаляется файл, не закрыты все потоки для этого файла oirren Общие вопросы по Java, Java SE, Kotlin 1 20.12.2009 21:12