
Saludos.
Escrito 16 marzo 2009 - 11:00
Escrito 16 marzo 2009 - 11:02
Escrito 16 marzo 2009 - 11:06
Escrito 16 marzo 2009 - 11:24
constructor TThreadPing.Create(IP: String); begin cIP := IP; //guarda la IP en una variable privada inherited Create(True); Priority := tpTimeCritical; resume; end;
constructor TThreadPing.Create(IP: String); begin cIP := IP; //guarda la IP en una variable privada inherited Create(True); Priority := tpIdle; resume; end;
tpIdle
El hilo sólo ejecuta cuando el sistema esta parado. Windows no interrumpirá a otros hilos para ejecutar un hilo con prioridad tpIdle.
tpLowest
La prioridad del hilo está dos puntos por debajo de la normal.
tpLower
La prioridad del hilo está un punto por debajo de la normal.
tpNormal
El hilo tiene una prioridad normal.
tpHigher
La prioridad del hilo está un punto por encima de la normal.
tpHighest
La prioridad del hilo está dos puntos por encima de la normal.
tpTimeCritical
El hilo tiene la prioridad más alta.
Escrito 16 marzo 2009 - 11:59
Hilo1 := TThreadPing.Create().
Escrito 16 marzo 2009 - 12:40
Escrito 16 marzo 2009 - 01:24
Disculpa si pareciera que llevo la contraria... pero no comprendo. cIP no es privada a la clase, es local (puede accederse a ella desde toda la unit):a ver Delphius, trato de llevarte la secuencia:
la duda que tienes de la variable es lo mismo que hacerlo con atributos, el asunto es que siempre se crea una nueva instancia de la clase, y cada una se esta ejecutando por separado, de esta forma la variable nunca se sobreescribiria el valor, cosa que si sucederia si la sacamos del objeto y la declaramos publica en la unit.
var FMain: TFMain; Conteo: Integer; cIP: String; implementation
TThreadPing = class(TThread) private procedure SetReloj; protected procedure Execute; override; public Host: String; S: TLabel; Recibe: TIdIcmpClient; G: TJvGIFAnimator; constructor Create(IP: String; Destino: TLabel; Imagen: TJvGIFAnimator); end;
constructor TThreadPing.Create(IP: String; Destino: TLabel; Imagen: TJvGIFAnimator); begin cIP := IP; //guarda la IP en una variable privada S := Destino; G := Imagen; inherited Create(False); end;
Puede que como dices que no haya problemas. En ocasiones no es necesario tener referencias a los objetos que creamos. Tal vez este sea un caso. Nomás me resulta extraño puesto que por lo que he estado leyendo en la ayuda, y en algunos ejemplos, sobre la clase TTHread, veo que sigue la misma regla que para cualquier objeto:Con respecto de crearlos sin asignarlo a una variable no tiene ningun problema, no veo cual seria la diferencia.
NOTA: Estoy hablando en base a experiencia personal, no tengo ninguna documentacion al respecto si alguien puede ilustrarnos al respecto estare muy agradecido, mi formacion con los hilos es auto didacta.
Hilo1.Suspend; Sleep(200); Hilo2.Resume;
Escrito 16 marzo 2009 - 01:45
for i := 0 to 23 do PingTo(ListIP[i]);
Escrito 16 marzo 2009 - 01:54
Escrito 16 marzo 2009 - 02:08
No es llevar la contraria, es ue cuando se tiene razon hay que decirlo...
si, no me habia fijado donde fue a parar el cIp, en mi idea era una variable interna del TThread que recibe el valor por un parametro del create, ahi llevas la razon...
Con respecto a la destruccion no lo habia pensado, y me gusta lo que propones, un solo hilo que haga todos los pines.
Escrito 16 marzo 2009 - 02:17
// . . . procedure TForm1.FormCreate(Sender: TObject); var Index, IP: Integer; begin IP := inet_addr('143.1.14.200'); if CloseHandle(IcmpCreateFile) then for Index := Low(Reply) to High(Reply) do begin Reply[Index].Address.S_addr := IP; CreateThread(nil, 0, @Thread, Ptr(Index), 0, PDWORD(0)^); Inc(PChar(@IP)[3]); end; end; procedure TForm1.PingStatus(var Message: TMessage); const Colors: array [Boolean] of TColor = (clRed, clBlack); var x, y: Cardinal; Str: string; begin x := (Message.WParam mod 3) * 300; y := (Message.WParam div 3) * 60; with Reply[Message.WParam] do begin Canvas.Font.Color := clBlack; Canvas.TextOut(x + 50, y, inet_ntoa(Address)); case Status of 11000: Str := 'IP_SUCCESS'; 11001: Str := 'IP_BUF_TOO_SMALL'; 11002: Str := 'IP_DEST_NET_UNREACHABLE'; // . . .
Escrito 16 marzo 2009 - 02:36
...Yo me imagino tener 24 hilos creados y mantenerlos (aunque en la ayuda dicen que no es aconsejable tener más de 16). Mandarlos a suspender por tiempo y volverlos a ejecutar. No me parece demasiado viable crear y destruir cada dos pos tres...
Y ahora ando pensando si es bueno tener 24 hilos.... ¿porqué no uno como comentó Domingo? La pregunta que me hago es si es muy adecuado que atienda a todos... ¿"aguantará"?...
...Finalmente considero que el rango razonable de hilos por proceso para este tipo de aplicaciones es de 256 a 1024...
Escrito 16 marzo 2009 - 05:04
Escrito 17 marzo 2009 - 10:13
Hola Javier, no comprendo del todo el código (para variar
...Yo me imagino tener 24 hilos creados y mantenerlos (aunque en la ayuda dicen que no es aconsejable tener más de 16). Mandarlos a suspender por tiempo y volverlos a ejecutar. No me parece demasiado viable crear y destruir cada dos pos tres...
En este caso no se debe usar la suspensión porque consume ciclos de procesador al llamar a las APIs necesarias las cuales "entran" hasta el nucleo. Crear y Destruir (el objeto) es tambien una mala idea
Y ahora ando pensando si es bueno tener 24 hilos.... ¿porqué no uno como comentó Domingo? La pregunta que me hago es si es muy adecuado que atienda a todos... ¿"aguantará"?...
Pues seoane no especifico la cantidad de hilos, pero si utilizó el plural. Si crearas un solo hilo funcionaria, pero debes considerar que si todas las PCs estan "desconectadas" excepto la ultima, el retardo se incrementaria en cada repeticion y habria una respuesta de tiempo de ese unico equipo despues de un intervalo prolongado.
...Finalmente considero que el rango razonable de hilos por proceso para este tipo de aplicaciones es de 256 a 1024...
Salud.
if Message.Msg = WM_USER then ....
Keeping track of too many threads consumes CPU time; the recommended limit is 16 active threads per process on single processor systems.
Escrito 17 marzo 2009 - 02:38
...cuando hay echo no muestra "IP_SUCCESS", ¿es así expresamente?...
Escrito 17 marzo 2009 - 02:45
Public Enum IP_STATUS IP_STATUS_BASE = 11000 IP_SUCCESS = 0 IP_BUF_TOO_SMALL = (11000 + 1) IP_DEST_NET_UNREACHABLE = (11000 + 2) IP_DEST_HOST_UNREACHABLE = (11000 + 3) IP_DEST_PROT_UNREACHABLE = (11000 + 4) IP_DEST_PORT_UNREACHABLE = (11000 + 5) IP_NO_RESOURCES = (11000 + 6) IP_BAD_OPTION = (11000 + 7) IP_HW_ERROR = (11000 + 8) IP_PACKET_TOO_BIG = (11000 + 9) IP_REQ_TIMED_OUT = (11000 + 10) IP_BAD_REQ = (11000 + 11) IP_BAD_ROUTE = (11000 + 12) IP_TTL_EXPIRED_TRANSIT = (11000 + 13) IP_TTL_EXPIRED_REASSEM = (11000 + 14) IP_PARAM_PROBLEM = (11000 + 15) IP_SOURCE_QUENCH = (11000 + 16) IP_OPTION_TOO_BIG = (11000 + 17) IP_BAD_DESTINATION = (11000 + 18) IP_ADDR_DELETED = (11000 + 19) IP_SPEC_MTU_CHANGE = (11000 + 20) IP_MTU_CHANGE = (11000 + 21) IP_UNLOAD = (11000 + 22) IP_ADDR_ADDED = (11000 + 23) IP_GENERAL_FAILURE = (11000 + 50) MAX_IP_STATUS = 11000 + 50 IP_PENDING = (11000 + 255) PING_TIMEOUT = 200 End Enum
Escrito 17 marzo 2009 - 03:00
...Encontré esto :
delphi
Public Enum IP_STATUS IP_STATUS_BASE = 11000 IP_SUCCESS = 0 IP_BUF_TOO_SMALL = (11000 + 1) // . . .
...
...Muy bueno e interesante el manejo que haces Little Bro
...
Escrito 17 marzo 2009 - 03:18
Esa parte si la entendí, se que creas un hilo por cada IP y vas asociando a cada hilo con el índice del vector.
Delphius; Te explico brevemente, cuando se crea el formulario (FormCreate) defino los IPs de todos los elementos del vector Reply, aparte de lo obvio lo hice de esta forma para poder inicializarlos de forma no secuencial (Ej. 192.168.1.2, 192.168.2.1, 192.168.1.30).
Al momento de inicializarlos tambien creo un hilo por cada elemento y al hilo le paso como parametro el indice del elemento en el vector al que habra de manejar cada hilo procesa individualmente un elemento y por ende un IP, el resultado del éco junto con el indice es enviado al formulario en forma de mensaje.
¡Gracias! No había visto ese pequeño detalleAqui tu pregunta, en la linea 13 de Unit1.pas esta el valor del mensaje que ha de procesar ; message WM_USER;. Esta es la forma en que el Delphi maneja los mensajes, y como ya habras confirmado solo maneja el mensaje definido (para procesar cualquier mensaje podrías optar por un case en Application.OnMessage).
Salud
procedure PingStatus(var Message: TMessage); message WM_USER;
Escrito 18 marzo 2009 - 06:38
Escrito 18 marzo 2009 - 09:33