Форум: "Начинающим";
Текущий архив: 2008.09.14;
Скачать: [xml.tar.bz2];
ВнизПинг Найти похожие ветки
← →
DeeNamid © (2008-08-04 12:48) [0]Вопрос такой, делаю пять потоков которые пингуют каждый свою машину и выводять результаты на пять окон, проблема с icmp-компонентом. Все пять потоков толкутся около icmp.ping() и результаты пинга искажаются.
Код примерно такой:
procedure Tping1.Execute;
begin
while not (terminated or application.Terminated) do begin
//EnterCriticalSection(CS);
res:=ping_func(ip_addres);
//LeaveCriticalSection(CS);
synchronize(print_res);
end;
end;
function Tping1.ping_func(host:string):integer;
var i,failed: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;
Когда ставишь критическую секцию результаты отображаются адекватно, но пока один поток пингует все остальные его ждут. Как сделать так что бы все пинговалось независимо друг от друга?
← →
Сергей М. © (2008-08-04 12:53) [1]
> Как сделать так что бы все пинговалось независимо друг от
> друга?
>
Каждый поток должен создавать и юзать свой собственный экз-р класса TIdICMP.
← →
DeeNamid © (2008-08-04 12:54) [2]Так и сделано вот полный вид execut"a
procedure Tping1.Execute;
var b:boolean;i:integer;
begin
FreeOnTerminate:=true;
b:=true;
icmp:=TIdIcmpClient.Create(nil);
while not (terminated or application.Terminated) do begin
EnterCriticalSection(CS);
res:=ping_func(ip_addres);
LeaveCriticalSection(CS);
synchronize(print_res);
end;
icmp.Destroy;
end;
← →
DeeNamid © (2008-08-04 12:55) [3]Так и сделано вот полный вид execut"a
procedure Tping1.Execute;
var b:boolean;i:integer;
begin
FreeOnTerminate:=true;
b:=true;
icmp:=TIdIcmpClient.Create(nil);
while not (terminated or application.Terminated) do begin
EnterCriticalSection(CS);
res:=ping_func(ip_addres);
LeaveCriticalSection(CS);
synchronize(print_res);
end;
icmp.Destroy;
end;
← →
Сергей М. © (2008-08-04 12:58) [4]
> Так и сделано
Нет, сделано не так.
Создавать-то ты создаешь по экземпляру на каждый поток, а юзаешь в каждом потоке один и то же экз-р.
← →
DeeNamid © (2008-08-04 13:02) [5]Недопонял. Как юзать разные экземпляры?
← →
Сергей М. © (2008-08-04 13:04) [6]function Tping1.ping_func(ICMP: TIdICMP; host:string):integer;
var i,failed: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 Tping1.Execute;
var
ICMPInstance: TIdICMP;
begin
..
ICMPInstance:=TIdIcmpClient.Create(nil);
try
while not (terminated or application.Terminated) do begin
res:=ping_func(ICMPInstance, ip_addres);
synchronize(print_res);
end;
finally
ICMPInstance.Free;
end;
..
end;
← →
antonn © (2008-08-04 13:20) [7]Ого, Сергей показал готовый код, где то здесь подвох! %)
← →
Сергей М. © (2008-08-04 13:42) [8]
> antonn © (04.08.08 13:20) [7]
Подвох не у меня , а у автора - область видимости ид-ра icmp он не удосужился уточнить)
← →
Anatoly Podgoretsky © (2008-08-04 13:59) [9]Да он вообще мало информации предоставил, зато он предоставил нам возможность проявиться телепатические способности.
← →
DeeNamid © (2008-08-04 14:22) [10]Ну смотрите тады ))
Главная форма:
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.
Как-то так. Сделал как ты сказал, ничего не изменилось.
← →
Dennis I. Komarov © (2008-08-04 14:25) [11]> [7] antonn © (04.08.08 13:20)
Значок видишь?
← →
DeeNamid © (2008-08-04 14:31) [12]Ты о чем?
← →
DeeNamid © (2008-08-04 14:58) [13]Куда-то все пропали... Помогите прояснить проблему. Почему не получается сделать так что-бы пять потоков независимо друг от друга корректно работали.
← →
Сергей М. © (2008-08-04 15:47) [14]
> DeeNamid © (04.08.08 14:58) [13]
А в чем, по-твоему, выражается их "зависимость друг от друга", в данный момент, т.е. при реализации, приведенной тобой в [10] ?
← →
DeeNamid © (2008-08-04 16:01) [15]Зависимость заключается в том что все пять потоков выводят на экран одни и те же значения.
Есть пять потоков и пять компонентов memo, на которые должны выводиться результаты пинга. Если использовать критическую секцию то все происходит нормально, то есть в каждом окошке отображаются корректные результаты. Но в этом случае пока пингует один поток, остальные его ждут, а это не гуд. Если же закомментировать эту секцию, то происходит следующее - все окошки отображают одни и те же цифры, при чем при отладке в watch"е видно что в процедуре print_res сам res для всех потоков имеет одинаковое значение. Вот в этом и вопрос - почему так происходит что res открыт для всех потоков, если он является локальной переменной класа TPing?
← →
Сергей М. © (2008-08-04 16:13) [16]
> res для всех потоков имеет одинаковое значение
Какое конкретно ?
← →
DeeNamid © (2008-08-04 16:16) [17]Ну к примеру 154, тогда на вывод получается:
Время до хоста: 154 ms
и так пять раз на все окна.
← →
Medbe}I{onok XML © (2008-08-04 16:22) [18]результат пинга число?
убрать всю эту ахинею. после окончания пинга и получения результата посылать главному окну сообщение, результат передавать в WParam или LParam
← →
DeeNamid © (2008-08-04 16:25) [19]Что-то как-то ты категорично вещаешь. Объясни подробнее плиз что такое
> результат передавать в WParam или LParam?
← →
Сергей М. © (2008-08-04 16:25) [20]А ты вообще понимаешь, что означает и как вычисляется св-во MsRoundTripTime ?
Оно никаким боком не относится к "время до хоста".
← →
DeeNamid © (2008-08-04 16:27) [21]Ладно это не важно, мне надо понять в чем проблема, почему локальную переменную имеют все подряд?
← →
Medbe}I{onok XML © (2008-08-04 16:28) [22]procedure Tping.Execute;
var icmp: TIdIcmpClient;
begin
FreeOnTerminate:=true; //Это в конструктор убрать
icmp:=TIdIcmpClient.Create(nil);
while not (terminated or application.Terminated) do begin
res:=ping_func(icmp,ip_addres);
end;
icmp.Destroy;
PostMessage(fMainFormHandle,WM_MYPING_MSG,<fNumberForMemo>,LParam(res));
end;
← →
Medbe}I{onok XML © (2008-08-04 16:29) [23]fMainFormHandle (хендл окна с лежащим не ём мемом) и fNumberForMemo (в каком мемо рисовать результат) передавать конструктору вторичного потока.
← →
Medbe}I{onok XML © (2008-08-04 16:31) [24]Точнее так, если там надо пинговать пока рак не свистнет:
procedure Tping.Execute;
var icmp: TIdIcmpClient;
begin
FreeOnTerminate:=true; //Это в конструктор убрать
icmp:=TIdIcmpClient.Create(nil);
while not (terminated or application.Terminated) do begin
res:=ping_func(icmp,ip_addres);
PostMessage(fMainFormHandle,WM_MYPING_MSG,<fNumberForMemo>,LParam
end;
icmp.Destroy;
(res));
end;
← →
Сергей М. © (2008-08-04 16:32) [25]
> почему локальную переменную имеют все подряд?
Никто ее не "имеет")
С логикой в твоем коде все более-менее в порядке.
Пробуй пинговать хосты из разных концов Тырнета - получишь разные результаты.
← →
DeeNamid © (2008-08-04 16:33) [26]То есть,
constructor Tping.create(ip_addr: string;i:integer;fMainFormHandle;fNumberForMemo);
так? Номер мемо просто цифра? И где взять хендл ?
← →
Medbe}I{onok XML © (2008-08-04 16:36) [27]constructor Tping.create(ip_addr: string;fMainFormHandle : HWND;fNumberForMemo : integer);
← →
Medbe}I{onok XML © (2008-08-04 16:38) [28]procedure TForm1.Button1Click(Sender: TObject);
begin
ping1:=Tping.Create("93.158.134.3",Handle,1);
ping2:=Tping.Create("172.21.161.34",Handle,2);
ping3:=Tping.Create("172.21.61.44",,Handle,3);
ping4:=Tping.Create("10.61.1.126",Handle,4);
ping5:=Tping.Create("172.21.61.46",Handle,5);
← →
Сергей М. © (2008-08-04 16:41) [29]
> Medbe}I{onok XML © (04.08.08 16:38) [28]
Ну и какая нафих разница ? Что, от вида синхронизации зависит трип-тайм ?)
← →
Medbe}I{onok XML © (2008-08-04 16:41) [30]я его спасаю от ужасов print_res
← →
Сергей М. © (2008-08-04 16:43) [31]
> спасаю от ужасов print_res
>
На якобы имеющее место "проблему" эти "ужасы" никак не влияют)
← →
Medbe}I{onok XML © (2008-08-04 16:44) [32]к тому же будет побочный положительный эффект:
нитка и главная форма потеряют имеющуюся чудовищную взаимозависимость между собой и отлаживать все станет проще.
← →
Medbe}I{onok XML © (2008-08-04 16:45) [33]На якобы имеющее место "проблему" эти "ужасы" никак не влияют)
Влияют на скорость понимания что они и правда не влияют.
:)
← →
DeeNamid © (2008-08-04 16:54) [34]
> Сергей М.
Смотри как интересно получается
memo1:
Время до хоста: 93ms
Время до хоста: 141ms
Время до хоста: 109ms
Время до хоста: 94ms
Время до хоста: 594ms
memo2:
Время до хоста: 62ms
Время до хоста: 93ms
Время до хоста: 141ms
Время до хоста: 125ms
Время до хоста: 94ms
Время до хоста: 579ms
memo3:
Время до хоста: 62ms
Время до хоста: 93ms
Время до хоста: 141ms
Время до хоста: 125ms
Время до хоста: 94ms
Время до хоста: 579ms
memo4:
Время до хоста: 62ms
Время до хоста: 93ms
Время до хоста: 141ms
Время до хоста: 125ms
Время до хоста: 94ms
Время до хоста:579ms
memo5:
Время до хоста: 62ms
Время до хоста: 93ms
Время до хоста: 141ms
Время до хоста: 109ms
Время до хоста: 78ms
Время до хоста: 579ms
Причем memo1 это yandex.ru а остальные наш филиал через vpn.
А вот что будет если внести ping_func в критическую секцию
memo1:
Превышен интервал ожидания
Время до хоста: 1454ms
Время до хоста: 1218ms
Время до хоста: 1469ms
Время до хоста: 1703ms
Время до хоста: 1422ms
memo2:
Время до хоста: 922ms
Время до хоста: 531ms
Время до хоста: 875ms
Превышен интервал ожидания
Время до хоста: 593ms
Время до хоста: 344ms
memo3:
Время до хоста: 93ms
Время до хоста: 125ms
Время до хоста: 171ms
Время до хоста: 110ms
Время до хоста: 297ms
memo4:
Время до хоста: 94ms
Время до хоста: 922ms
Время до хоста: 188ms
Время до хоста: 265ms
Время до хоста: 297ms
Время до хоста: 125ms
memo5:
Время до хоста: 437ms
Превышен интервал ожидания
Время до хоста: 141ms
Время до хоста: 313ms
Время до хоста: 94ms
Время до хоста: 125ms
Другое дело правда?
← →
Сергей М. © (2008-08-04 17:08) [35]
> memo1 это yandex.ru а остальные наш филиал через vpn
И что ?
Я видижу, что цифирь для Яндекса отличается от цифири для вашей vpn.
А ты утверждал, что цифирь одинакова для любых хостов )
← →
DeeNamid © (2008-08-04 17:16) [36]Ну ты же видишь разницу в первом случае и во втором? А получилось так просто потому что я всего несколько строк написал, если посмотреть дальше будет видно сходство. Оно и правда не точно идентично, но ведь ясно же что какой-то косяк есть. Я настаиваю на том что после внесения результата в res и до вывода на экран, значение res искажается каким-то другим потоком. И хочу понять почему так происходит? Может есть какие-то другие методы хранения и защиты локальных переменных (кроме threadvar и того как сделано у меня)?
← →
Medbe}I{onok XML © (2008-08-04 17:24) [37]Я настаиваю на том что после внесения результата в res и до вывода на экран, значение res искажается каким-то другим потоком.
Это точно метапоток из галактик-футбалл.
← →
DeeNamid © (2008-08-04 17:25) [38]Точнее даже не так. Посмотри что получается:
function Tping.ping_func(icmp:TIdIcmpClient;host:string):integer;
var i,failed:integer;
begin
icmp.ReceiveTimeout:=3000;
icmp.Host:=host;
EnterCriticalSection(CS); //!
icmp.Ping();
LeaveCriticalSection(CS);//!
if icmp.ReplyStatus.ReplyStatusType<>rsTimeOut then
ping_func:=icmp.ReplyStatus.MsRoundTripTime
else
ping_func:=0;
end;
Так тоже все работает нормально. Дело в самом пинге. И теперь я вообще ничего не понимаю. Хотя и раньше мало что понимал ))
← →
Medbe}I{onok XML © (2008-08-04 17:25) [39]да причем так хитро искажается, что везде одинаково.
← →
DeeNamid © (2008-08-04 17:26) [40]
> Medbe}I{onok XML
Харе прикалываться :)) Посмотри на 38 пост, с пингом какие-то замороки.
Страницы: 1 2 3 вся ветка
Форум: "Начинающим";
Текущий архив: 2008.09.14;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.054 c