Ejecución de subproceso único
La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la
versión revisada el 22 de mayo de 2019; las comprobaciones requieren
4 ediciones .
Ejecución de subproceso único |
---|
Ejecución de subproceso único |
Descrito en Patrones de diseño |
No |
La ejecución de subproceso único ( ing. Single Threaded Execution o ing. Critical Section [1] ) es un patrón de diseño paralelo que evita una llamada de método competitiva, lo que prohíbe la ejecución paralela de este método.
Motivos
- La clase contiene métodos que actualizan o establecen valores en variables de instancia de clase o variables de clase.
- El método manipula recursos externos que admiten solo una operación a la vez.
- Los métodos de clase pueden ser llamados en paralelo por diferentes subprocesos.
- No hay límite de tiempo que requiera que un método se ejecute inmediatamente tan pronto como se llame.
Consecuencias
- + Proporciona seguridad para hilos
- − El rendimiento puede verse reducido
- − Interbloqueo posible
Ejemplo de implementación
Ejemplo de C#
utilizando el sistema ;
utilizando System.Threading ;
espacio de nombres Digital_Patterns.Concurrency.Single_Thread_Execution
{
/// <summary>
/// Las instancias de la clase <see cref="TrafficSensor"/> están asociadas con un
sensor de tráfico ///, que captura el paso de un lugar determinado en
/ // un carril de tráfico.
/// </summary>
class TrafficSensor
{
private static Int32 mID = 0 ;
ITrafficObserver privado _observador ;
IsRun booleano público { get ; conjunto ; }
privado Int32_id ; _
/// <summary>
/// Constructor
/// </summary>
/// <param name="observer">Un objeto para señalar que el
/// sensor de tráfico asociado con este objeto ///
detecta un automóvil que pasa .</param>
public TrafficSensor ( observador de ITrafficObserver ) { _id = ++ mID ; _observador = observador ; EsEjecutar = verdadero ; hilo nuevo ( ejecutar ). Inicio (); }
/// <summary>
/// Lógica general para el subproceso de este objeto
/// </summary>
private void Run ()
{
while ( IsRun )
{
motitorSensor ();
}
}
mRnd aleatorio estático privado = nuevo aleatorio (); /// <summary> /// Este método llama al método de detección del objeto cuando /// el sensor de tráfico asociado detecta /// un automóvil que pasa /// </summary> private void motitorSensor () { //TODO Something hilo _ Dormir ( mRnd . Siguiente ( 1000 )); mensaje = Sistema ._ _ reflexión _ Información del método . GetCurrentMethod (). nombre ; consola _ WriteLine ( Cadena . Formato ( @"{0} {1} +1" , _id , msg ));
detectar ();
}
/// <summary>
/// Este método es llamado por el método <see cref="motitorSensor"/>
/// para informar el paso de un vehículo
/// al observador de este objeto
/// </summary >
detección de vacío privado () { _observer . vehículoAprobado (); }
/// <summary>
/// Las clases deben implementar esta interfaz,
/// para que el objeto <see cref="TrafficSensor"/> pueda informarles sobre el paso de
/// vehículos
/// </summary>
public interface ITrafficObserver
{
/ // <summary>
/// Se llama cuando <see cref="TrafficSensor"/> detecta
/// un vehículo que pasa.
/// </summary>
void vehículoAprobado ();
}
}
}
utilizando el sistema ;
espacio de nombres Digital_Patterns.Concurrency.Single_Thread_Execution
{
/// <summary>
/// Las instancias de la clase <see cref="TrafficSensorController"/> almacenan el
/// número total actual de vehículos que pasan por los sensores de tráfico
/// asociados con el instancia.
/// </summary>
clase TrafficSensorController : TrafficSensor . ITrafficObserver
{
private Int32 _vehicleCount = 0 ;
/// <resumen>
/// Este método se llama cuando el
sensor de movimiento del vehículo /// detecta el paso de un vehículo. Incrementa
/// el contador de la máquina en uno.
/// </summary>
public void vehículo aprobado ()
{
lock ( este )
{
++ _vehicleCount ;
}
}
/// <summary>
/// Pone a cero el contador del coche
/// </summary>
/// <returns></returns>
public Int32 GetAndClearCount ()
{
lock ( this )
{
Int32 count = _vehicleCount ;
_vehicleCount = 0 ;
recuento de retorno ; } } } }
utilizando el sistema ;
utilizando System.Threading ;
espacio de nombres Digital_Patterns.Concurrency.Single_Thread_Execution
{
/// <summary>
/// Las instancias de la clase <see cref="TrafficTransmitter"/> son responsables de
/// pasar un valor que determina el número de automóviles que pasan por este
/// carretera por minuto.
/// </summary>
class TrafficTransmitter
{
privado TrafficSensorController _conrtoller ;
Subproceso privado _miSubproceso ;
IsRun booleano público { get ; conjunto ; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="conrtoller">Desde <see cref="TrafficSensorController"/> este objeto
/// recibirá el valor del contador del número de
coches / // pasados</param>
public TrafficTransmitter ( TrafficSensorController conrtoller )
{
_conrtoller = conrtoller ;
_myThread = nuevo hilo ( ejecutar );
EsEjecutar = verdadero ;
_miHilo . Inicio ();
}
/// <summary>
/// Pasa el valor del contador del número de máquinas pasadas
/// durante el intervalo de tiempo
/// </summary>
private void Run ()
{
while ( IsRun )
{
Thread . Dormir ( 10000 );
Transmitir ( _conrtoller . GetAndClearCount ());
}
}
privado void Transmit ( Int32 count )
{
//TODO Something
var msg = System . reflexión _ Información del método . GetCurrentMethod (). nombre ;
consola _ WriteLine ( String . Format ( @"{0} {1}" , msj , count ));
}
}
}
utilizando el sistema ;
utilizando Digital_Patterns.Concurrency.Single_Thread_Execution ;
espacio de nombres Digital_Patterns
{
class Program
{
static void Main ( string [] args )
{
var controller = new TrafficSensorController ();
var transmisor = nuevo TrafficTransmitter ( controlador );
consola _ WriteLine ( @"Presione cualquier tecla para comenzar y presione nuevamente para finalizar" );
consola _ Clave de lectura ();
var sensor1 = nuevo TrafficSensor ( controlador );
var sensor2 = nuevo TrafficSensor ( controlador );
consola _ Clave de lectura ();
sensor1 . EsEjecutar = falso ;
sensor2 . EsEjecutar = falso ;
transmisor _ EsEjecutar = falso ;
consola _ escribirLinea ();
}
}
}
Enlaces
- Marca grandioso. Patrones en Java Volumen 1: un catálogo de patrones de diseño reutilizables ilustrados con UML. - Wiley & Sons, 1998. - 480 p. — ISBN 0471258393 . (ver sinopsis (inglés) )