videos populares poner para nuevos mejores los hashtags como añadir agregar delphi delphi-2010 delphi-2009 delphi-xe tmonitor

populares - ¿Para qué sirve TMonitor en la unidad Delphi System?



nuevos hashtags youtube (1)

TMonitor combina la noción de una sección crítica (o un mutex simple) junto con una variable de condición. Puede leer sobre qué es un "monitor" aquí: http://en.wikipedia.org/wiki/Monitor_%28synchronization%29 .

En cualquier lugar donde use una sección crítica, puede usar un monitor. En lugar de declarar una TCriticalSection, puedes crear una instancia de TObject y luego usarla.

TMonitor.Enter(FLock); try // protected code finally TMonitor.Exit(FLock); end;

Donde FLock es cualquier instancia de objeto. Normalmente, solo creo un TObject:

FLock := TObject.Create;

Después de leer los artículos "Simmering Unicode, llevar DPL a ebullición" y "Simmering Unicode, llevar a DPL a ebullición (Parte 2)" de "The Oracle at Delphi" (Allen Bauer), Oracle es todo lo que entiendo :)

El artículo menciona Delphi Parallel Library (DPL), bloquea estructuras de datos libres, bloqueos mutuos de exclusión y variables de condición (este artículo de Wikipedia se reenvía a '' Monitor (synchronization) '', y luego introduce el nuevo tipo de registro TMonitor para la sincronización de hilos y describe algunos de sus métodos.

¿Hay artículos de introducción con ejemplos que muestran cuándo y cómo se puede utilizar este tipo de registro Delphi? Hay alguna documentación en línea.

  • ¿Cuál es la principal diferencia entre TCriticalSection y TMonitor?

  • ¿Qué puedo hacer con los métodos Pulse y PulseAll ?

  • ¿Tiene una contraparte, por ejemplo, en C # o en el lenguaje Java?

  • ¿Hay algún código en la RTL o la VCL que use este tipo (por lo que podría servir como un ejemplo)?

Actualización: el artículo ¿Por qué se ha duplicado el tamaño de TObject en Delphi 2009? explica que cada objeto en Delphi ahora se puede bloquear usando un registro TMonitor, al precio de cuatro bytes adicionales por instancia.

Parece que TMonitor se implementa de forma similar a los bloqueos intrínsecos en el lenguaje Java :

Cada objeto tiene un bloqueo intrínseco asociado a él. Por convención, un hilo que necesita acceso exclusivo y consistente a los campos de un objeto tiene que adquirir el bloqueo intrínseco del objeto antes de acceder a ellos, y luego liberar el bloqueo intrínseco cuando termina con ellos.

Wait , Pulse y PulseAll en Delphi parecen ser contrapartes de wait() , notifyAll() y notifyAll() en el lenguaje de programación Java. Corrígeme si estoy equivocado :)

Actualización 2: código de ejemplo para una aplicación Producer / Consumer utilizando TMonitor.Wait y TMonitor.PulseAll , basado en un artículo sobre métodos guardados en los tutoriales de Java (tm) (los comentarios son bienvenidos):

Este tipo de aplicación comparte datos entre dos hilos: el productor, que crea los datos, y el consumidor, que hace algo con eso. Los dos hilos se comunican usando un objeto compartido. La coordinación es esencial: el hilo del consumidor no debe intentar recuperar los datos antes de que el subproceso del productor lo haya entregado, y el hilo del productor no debe intentar entregar nuevos datos si el consumidor no ha recuperado los datos anteriores.

En este ejemplo, los datos son una serie de mensajes de texto, que se comparten a través de un objeto de tipo Drop:

program TMonitorTest; // based on example code at http://download.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html {$APPTYPE CONSOLE} uses SysUtils, Classes; type Drop = class(TObject) private // Message sent from producer to consumer. Msg: string; // True if consumer should wait for producer to send message, false // if producer should wait for consumer to retrieve message. Empty: Boolean; public constructor Create; function Take: string; procedure Put(AMessage: string); end; Producer = class(TThread) private FDrop: Drop; public constructor Create(ADrop: Drop); procedure Execute; override; end; Consumer = class(TThread) private FDrop: Drop; public constructor Create(ADrop: Drop); procedure Execute; override; end; { Drop } constructor Drop.Create; begin Empty := True; end; function Drop.Take: string; begin TMonitor.Enter(Self); try // Wait until message is available. while Empty do begin TMonitor.Wait(Self, INFINITE); end; // Toggle status. Empty := True; // Notify producer that status has changed. TMonitor.PulseAll(Self); Result := Msg; finally TMonitor.Exit(Self); end; end; procedure Drop.Put(AMessage: string); begin TMonitor.Enter(Self); try // Wait until message has been retrieved. while not Empty do begin TMonitor.Wait(Self, INFINITE); end; // Toggle status. Empty := False; // Store message. Msg := AMessage; // Notify consumer that status has changed. TMonitor.PulseAll(Self); finally TMonitor.Exit(Self); end; end; { Producer } constructor Producer.Create(ADrop: Drop); begin FDrop := ADrop; inherited Create(False); end; procedure Producer.Execute; var Msgs: array of string; I: Integer; begin SetLength(Msgs, 4); Msgs[0] := ''Mares eat oats''; Msgs[1] := ''Does eat oats''; Msgs[2] := ''Little lambs eat ivy''; Msgs[3] := ''A kid will eat ivy too''; for I := 0 to Length(Msgs) - 1 do begin FDrop.Put(Msgs[I]); Sleep(Random(5000)); end; FDrop.Put(''DONE''); end; { Consumer } constructor Consumer.Create(ADrop: Drop); begin FDrop := ADrop; inherited Create(False); end; procedure Consumer.Execute; var Msg: string; begin repeat Msg := FDrop.Take; WriteLn(''Received: '' + Msg); Sleep(Random(5000)); until Msg = ''DONE''; end; var ADrop: Drop; begin Randomize; ADrop := Drop.Create; Producer.Create(ADrop); Consumer.Create(ADrop); ReadLn; end.

Ahora esto funciona como se esperaba, sin embargo hay un detalle que podría mejorar: en lugar de bloquear toda la instancia de Drop con TMonitor.Enter(Self); , Podría elegir un enfoque de bloqueo de grano fino, con un campo (privado) "FLock", utilizándolo solo en los métodos Put y Take de TMonitor.Enter(FLock); .

Si comparo el código con la versión de Java, también noto que no hay una InterruptedException en Delphi que se puede usar para cancelar una llamada de Sleep .

Actualización 3 : en mayo de 2011, una entrada de blog sobre OmniThreadLibrary presentó un posible error en la implementación de TMonitor. Parece estar relacionado con una entrada en Quality Central . Los comentarios mencionan que un parche ha sido provisto por un usuario de Delphi, pero no es visible.

Actualización 4 : una publicación de blog en 2013 mostró que, si bien TMonitor es "justo", su rendimiento es peor que el de una sección crítica.