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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 04.08.2008, 15:26   #1
DeeNamid
 
Регистрация: 24.07.2008
Сообщений: 4
Вопрос Проблема с потоками

Вопрос такой, делаю пять потоков, которые пингуют каждый свою машину и выводять результаты на пять окон. Проблема с icmp-компонентом. Все пять потоков толкутся около icmp.ping() и результаты пинга искажаются, то есть во всех окнах отображаются одинаковые значения количества миллисекунд.
Код примерно такой:

Главная форма:
Код:
type
 TForm1 = class(TForm)
   Memo1: TMemo;
   Button1: TButton;
   ComboBox1: TComboBox;
   Panel1: TPanel;
   Label7: TLabel;
   Label8: TLabel;
   Label9: TLabel;
   Label10: TLabel;
   Label11: TLabel;
   Label12: TLabel;
   Memo2: TMemo;
   Memo3: TMemo;
   Memo4: TMemo;
   Memo5: TMemo;
   Memo6: TMemo;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
   procedure Button2Click(Sender: TObject);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
 private
   ping1,ping2,ping3,ping4,ping5: Tping;
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

procedure TForm1.Button1Click(Sender: TObject);
begin
ping1:=Tping.Create('93.158.134.3',1);
ping2:=Tping.Create('172.21.161.34',2);
ping3:=Tping.Create('172.21.61.44',3);
ping4:=Tping.Create('10.61.1.126',4);
ping5:=Tping.Create('172.21.61.46',5);
 ping1.Resume;
 ping2.Resume;
 ping3.Resume;
 ping4.Resume;
 ping5.Resume;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
try
  ping1.Terminate;
  ping2.Terminate;
  ping3.Terminate;
  ping4.Terminate;
  ping5.Terminate;
except
end;
end;
Unit2:
Код:
type
 Tping = class(TThread)
 private
   memo_num:integer;ip_addres:string;
   res:integer;res_str:string;
 protected
   procedure Execute; override;
   function ping_func(icmp:TIdIcmpClient;host:string):integer;
   procedure print_res;
 public
   constructor create(ip_addr:string;i:integer);
 end;

var CS:TRTLCriticalSection;
implementation
uses Unit1;

function Tping.ping_func(icmp:TIdIcmpClient;host:string):integer;
begin
 icmp.ReceiveTimeout:=3000;
 icmp.Host:=host;
 icmp.Ping();
 if icmp.ReplyStatus.ReplyStatusType<>rsTimeOut then
   ping_func:=icmp.ReplyStatus.MsRoundTripTime
  else
   ping_func:=0;
end;

procedure Tping.Execute;
var icmp: TIdIcmpClient;
begin
 FreeOnTerminate:=true;
 icmp:=TIdIcmpClient.Create(nil);
 while not (terminated or application.Terminated) do begin
//EnterCriticalSection(CS);
 res:=ping_func(icmp,ip_addres);//мне кажется здесь заморочка с res
//LeaveCriticalSection(CS);
 sleep(0);
 synchronize(print_res);
 end;
 icmp.Destroy;
end;

procedure Tping.print_res;
begin
if res>0 then res_str:='Время до хоста: '+inttostr(res)+'ms' else res_str:='Превышен интервал ожидания';
case memo_num of
 1: Form1.memo2.Lines.add(res_str);
 2: Form1.memo3.Lines.add(res_str);
 3: Form1.memo4.Lines.add(res_str);
 4: Form1.memo5.Lines.add(res_str);
 5: Form1.memo6.Lines.add(res_str);
end;
Form1.memo1.lines.add('Поток номер: '+inttostr(memo_num));
Form1.Memo1.Lines.Add(res_str);
end;

constructor Tping.create(ip_addr: string;i:integer);
begin
ip_addres:=ip_addr;
memo_num:=i;
inherited create(true);
end;

initialization
 InitializeCriticalSection(CS);
end.
Когда включаешь процедуру пинга в критическую секцию, пингует адекватно, но мне нужно что-бы все потоки работали самостоятельно, отдельно друг от друга. Помогите решить проблему плиз.

Последний раз редактировалось Stilet; 04.08.2008 в 15:43.
DeeNamid вне форума Ответить с цитированием
Старый 04.08.2008, 16:29   #2
DeeNamid
 
Регистрация: 24.07.2008
Сообщений: 4
По умолчанию

Ну и тишина Напишу подробнее.
Есть пять потоков и пять компонентов memo, на которые должны выводиться результаты пинга. Если использовать критическую секцию то все происходит нормально, то есть в каждом окошке отображаются корректные результаты. Но в этом случае пока пингует один поток, остальные его ждут, а это не гуд. Если же закомментировать эту секцию, то происходит следующее - все окошки отображают одни и те же цифры, при чем при отладке в watch'е видно что в процедуре print_res сам res для всех потоков имеет одинаковое значение. Вот в этом и вопрос - почему так происходит что res открыт для всех потоков, если он является локальной переменной класа TPing?
DeeNamid вне форума Ответить с цитированием
Старый 04.08.2008, 17:36   #3
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Цитата:
res:=ping_func(icmp,ip_addres);//мне кажется здесь заморочка с res
А мне кажется стоит сделать или синхронизацию т.е. вынести эту функцию и присваивание res в отдельную процедуру или просто эту функцию расписать прямо в execute.
BOBAH13 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
работа с потоками Alex_Pro Общие вопросы .NET 1 01.07.2008 07:25
Как грамотно разделить данные между потоками? bagulma Общие вопросы Delphi 5 28.05.2008 22:41
C++, работа с потоками mat90x Помощь студентам 20 15.05.2008 22:20
Проблема с потоками vitalik007 Общие вопросы Delphi 1 11.03.2008 22:35
Ошибка при работе с потоками vitalik007 Общие вопросы Delphi 6 09.03.2008 09:25