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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> тупой нубский вопрос про потоки в Indy 
:(
    Опции темы
CompWorm
Дата 26.4.2008, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Допеределыватель
***


Профиль
Группа: Участник Клуба
Сообщений: 1689
Регистрация: 6.12.2004
Где: /

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



у меня тупой нубский вопрос про потоки в Indy плз не бейте больно.

вот решил проверить, что делает инеец, если к нему приходит второй запрос, пока не выполнился первый... и наблюдал не совсем понятную картину:

Код

type
  TSimpleClient = class(TObject)
    IP,
    Name        : String;
    Thread      : Pointer; //тут храним указатель на поток клиента
  end;
var Clients  : TList;     //сюда записываем подсоединившихся клиентов

бла бла бла...

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
  Msg    : String;   //сообщение
  i, z, z1: integer;
  F_main: TextFile;
begin
  {                     КЛИЕНТ ПРИСЛАЛ СООБЩЕНИЕ
   ну, первым делом, надо понять, кто это сообщение прислал...
   пробегаем по списку клиентов,
   в поисках указателя на поток, в котором пришло сообщение.
  }
  for i := 0 to Clients.Count - 1 do
  begin
    if Pointer(AContext)=TSimpleClient(Clients.Items[i]).Thread then
    begin
      { читаем, что прислал клиент }
      Msg:= AContext.Connection.IOHandler.ReadLn;
        if Msg='run' then begin
          randomize;
          z:=random(1000000);
          AssignFile(F_main, 'c:\'+inttostr(z)+'.txt');     
          try                                                        
          ReWrite(F_main);
          for z1:=0 to 100000000 do Write (F_main, 'Hello');                                 
          CloseFile(F_main);                                         
          except                                                     
          on EInOutError do ShowMessage ('Can''t Save your fucking file!');
          end;
        end;
      break; // впустую цикл не гоняем
    end;
  end;
end;


вот  smile 
так вот от сюда видно, что есть нечто под названием AContext, которое содержет нечто вроде потока, созданного самим INDY еще при подключении...

в результате этого у нас достаточно времени чтобы спокойно запустить 2 и более клиентов и послать серверу что-нибудь для активации записи данных в файл.

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

кто-нибудь может внести ясность в отношении 10 индейцев  smile 

Это сообщение отредактировал(а) CompWorm - 26.4.2008, 22:15


--------------------
PM MAIL   Вверх
CompWorm
  Дата 27.4.2008, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Допеределыватель
***


Профиль
Группа: Участник Клуба
Сообщений: 1689
Регистрация: 6.12.2004
Где: /

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



ну, раз никто не отвечает, давайте разобьем вопрос на несколько простых...

правда ли что TIdTCPServer работает в отдельном потоке и создает для каждого подключившегося клиента по еще одному потоку внутри себя (вне главного VCL потока, но внутри своего) ?

user posted image

Это сообщение отредактировал(а) CompWorm - 27.4.2008, 17:52


--------------------
PM MAIL   Вверх
MetalFan
Дата 27.4.2008, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



Цитата(CompWorm @  26.4.2008,  20:42 Найти цитируемый пост)
что либо я не совсем понимаю многопоточность, либо индейцы кривовато многопоточат

скорее первое.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
CompWorm
Дата 27.4.2008, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Допеределыватель
***


Профиль
Группа: Участник Клуба
Сообщений: 1689
Регистрация: 6.12.2004
Где: /

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



не стану спорить, но если у кого-то тут все в порядке с многопоточностью, можите пояснить принцип работы плз?

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


--------------------
PM MAIL   Вверх
MetalFan
Дата 27.4.2008, 21:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



самая большая ошибка в приведенном тобой коде - небезопасная работа с разделяемыми данными...


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
CompWorm
Дата 28.4.2008, 09:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Допеределыватель
***


Профиль
Группа: Участник Клуба
Сообщений: 1689
Регистрация: 6.12.2004
Где: /

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



MetalFan, 
наверно мой код не очень правильный и это мешает мне понять суть происходящего.
давайте тогда начнем с исправлений.
однако, я не очень большой спец в том, что делаю. поэтому, задавая вопросы, я пытаюсь повысить общий уровень своей эрудированности в данном вопросе.
но, ваши комментарии по поводу моей "ошибки в 17 строке" не позволяют мне сделать каких-либо качественных изменений в моем коде. 
не могли бы вы пояснить более детально, что в моем коде не так.


--------------------
PM MAIL   Вверх
MetalFan
Дата 28.4.2008, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



прочитай здесь на форуме статейку про многопоточность.
а более детально я тебе уже сказал - у тебя одновременная работа из нескольких потоков с одними и теми же данными


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
CompWorm
Дата 28.4.2008, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Допеределыватель
***


Профиль
Группа: Участник Клуба
Сообщений: 1689
Регистрация: 6.12.2004
Где: /

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



Цитата

прочитай здесь на форуме статейку про многопоточность.

она у меня уже в двух экземплярах распечатана)) прочел с удовольствием 2 раза, но видно не помогло  smile  )))

Цитата

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


какими? файл один и тот же? так я специально рандомлю чтоб не совпадало 
Код

   randomize;
          z:=random(1000000);
          AssignFile(F_main, 'c:\'+inttostr(z)+'.txt');     
          try                                                        
          ReWrite(F_main);
          for z1:=0 to 100000000 do Write (F_main, 'Hello');                                 
          CloseFile(F_main);                                         
          except                                                     
          on EInOutError do ShowMessage ('Can''t Save your fucking file!');
          end;

есть вероятность, но пока ни разу не случилось повторов smile (я понимаю, что так нельзя, но этот код я сделал для простого теста, чтобы понять, как устроен компонент сервера в индейцах, и конечно не собираюсь вероломно использовать в своих программах) 


Это сообщение отредактировал(а) CompWorm - 28.4.2008, 14:17


--------------------
PM MAIL   Вверх
MetalFan
Дата 28.4.2008, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



Цитата(CompWorm @  26.4.2008,  20:42 Найти цитируемый пост)
 for i := 0 to Clients.Count - 1 do

а это у тебя что?! где заполняется?


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
CompWorm
Дата 28.4.2008, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Допеределыватель
***


Профиль
Группа: Участник Клуба
Сообщений: 1689
Регистрация: 6.12.2004
Где: /

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



я представил кусок кода, ответственный за обработку приходящих сообщений (у меня вопрос про них). могу, если требуется выложить весь код.

MetalFan, а этот, я возможно плохо прокомментировал:
Цитата

var Clients  : TList;     //сюда записываем подсоединившихся клиентов

то есть, я мел в виду, что он заполняется при подключении новых клиентов в событии коннекта, чтобы был список присоединившихся клиентов.
соответственно, участок кода, который ты указал, не может быть выполнен минуя момент подключения, где список Clients  и пополняется очередной записью

Это сообщение отредактировал(а) CompWorm - 28.4.2008, 15:52


--------------------
PM MAIL   Вверх
MetalFan
Дата 29.4.2008, 08:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



Цитата(CompWorm @  28.4.2008,  15:51 Найти цитируемый пост)
то есть, я мел в виду, что он заполняется при подключении новых клиентов в событии коннекта, чтобы был список присоединившихся клиентов.
соответственно, участок кода, который ты указал, не может быть выполнен минуя момент подключения, где список Clients  и пополняется очередной записью

т.е. ты считаешь, что "событие коннекта" не может произойти "одновременно" с выполнением данного кода? имо, заблуждаешься



--------------------
There are always someone smarter than you...
PM MAIL   Вверх
CompWorm
Дата 29.4.2008, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Допеределыватель
***


Профиль
Группа: Участник Клуба
Сообщений: 1689
Регистрация: 6.12.2004
Где: /

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



 smile 
Код

...
 for i := 0 to Clients.Count - 1 do
  begin
    if Pointer(AContext)=TSimpleClient(Clients.Items[i]).Thread then
    begin
       {код, который НЕ может произойти, покуда в коннекте
         не пополнится список Clients типа TSimpleClient с указателем Thread: Pointer;
         на поток подключившегося клиента.
        }
    end;
   end;
...



--------------------
PM MAIL   Вверх
dumb
Дата 29.4.2008, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

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



Цитата(CompWorm @  28.4.2008,  15:14 Найти цитируемый пост)
прочел с удовольствием 2 раза, но видно не помогло
smile

не надо грозные смайлики вывешивать, лучше сконцентрируйся:
Цитата(CompWorm @  29.4.2008,  13:18 Найти цитируемый пост)
for i := 0 to Clients.Count - 1 do
пока ты в одном потоке крутишь этот цикл, может произойти подключение/отключение клиента, и твой список клиентов изменится. при этом цикл(когда выполнение к нему вернется) будет работать с несуществующими либо неполными данными.
PM MAIL   Вверх
CompWorm
Дата 29.4.2008, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Допеределыватель
***


Профиль
Группа: Участник Клуба
Сообщений: 1689
Регистрация: 6.12.2004
Где: /

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



Цитата

не надо грозные смайлики вывешивать, лучше сконцентрируйся:
Цитата(CompWorm @  29.4.2008,  13:18 Найти цитируемый пост)
for i := 0 to Clients.Count - 1 do
пока ты в одном потоке крутишь этот цикл, может произойти подключение/отключение клиента, и твой список клиентов изменится. при этом цикл(когда выполнение к нему вернется) будет работать с несуществующими либо неполными данными.

ха! а при отсоединении клиента происходит ожидание завершения потока, в котором выполняется уже неверный цикл... отличная заметка!
надо будет придумать защиту... к примеру, на каждый проход цикла поставить какую-нибудь проверку


я тут решил в мануалах индейцев порыться для просветления.
если вернуться к истокам темы, то я задавал, да простят меня админы, два вопроса:
- как устроена система потоков (статья)
- где находится и как выглядит очередь сообщений одного клиента (статья)

если я правильно понимаю то, что тут написано,
- потоков всегда на один больше, чем клиентов. в частном случае, когда сервер только активировался, создаётся один поток для прослушивания.
- все сообщения клиента стоят в очереди не основного потока, а записываются и регулируются планировщиком  property Scheduler: TIdScheduler. поэтому основной поток не виснет при получении новых сообщений, пока не выполнилось первое.

Я ПРАВИЛЬНО ВСЁ ПОНЯЛ? ?

ПС соответственно, моя схема выше неправильная.

Это сообщение отредактировал(а) CompWorm - 29.4.2008, 14:09


--------------------
PM MAIL   Вверх
MetalFan
Дата 29.4.2008, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



Цитата(CompWorm @  29.4.2008,  12:18 Найти цитируемый пост)
{код, который НЕ может произойти, покуда в коннекте
         не пополнится список Clients типа TSimpleClient с указателем Thread: Pointer;
         на поток подключившегося клиента.
        }

смотри сам. я тебе показал потокоНЕбезопасное место. считаешь, что все должно работать - аминь


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

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

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

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


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

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


 




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


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

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