Интернет магазин китайских планшетных компьютеров



Компьютеры - Single Thread Execution

01 мая 2011





Однопоточное выполнение — известный также под названием англ. Critical Section. Шаблон проектирования препятствующий конкурентному вызову метода, тем самым запрещая параллельное выполнение этого метода.

Мотивы

  • Класс содержит методы, которые обновляют или задают значения в переменных экземпляра класса или переменных класса.
  • Метод манипулирует внешними ресурсами, которые поддерживают только одну операцию в какой-то момент времени.
  • Методы класса могут вызываться параллельно различными потоками.
  • Не существует временного ограничения, которое требовало бы от метода немедленного выполнения, как только его вызывают.

Следствия

  • + Обеспечивается безопасность потоков
  • - Производительность может быть снижена
  • - Возможно взаимная блокировка

Пример реализации

Пример C#

using System;
using System.Threading;
 
namespace Digital_Patterns.Concurrency.Single_Thread_Execution
{
    /// <summary>
    /// Экземпляры класса <see cref="TrafficSensor"/> связаны с сенсором движения
    /// транспорта, который фиксирует прохождение машиной некоторого места на
    /// полосе движения.
    /// </summary>
    class TrafficSensor
    {
        private static Int32 mID = 0;
 
        private ITrafficObserver _observer;
 
        public Boolean IsRun { get; set; }
 
        private Int32 _id;
 
 
        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="observer">Объект, предназначенный для оповещения о том, что сенсор
        /// движения транспорта, связанный с этим объектом,
        /// обнаруживает проходящую машину.</param>
        public TrafficSensor
        {
            _id = ++mID;
            _observer = observer;
            IsRun = true;
            new Thread.Start;
        }
 
        /// <summary>
        /// Общая логика для потока этого объекта
        /// </summary>
        private void Run
        {
            while 
            {
                motitorSensor;
            }
        }
 
        private static Random mRnd = new Random;
        /// <summary>
        /// Этом метод вызывает метод detect объекта, когда
        /// связанный с ним сенсор движения транспорта фиксирует 
        /// проходящую машину
        /// </summary>
        private void motitorSensor
        {
            //TODO Something
            Thread.Sleep);
            var msg = System.Reflection.MethodInfo.GetCurrentMethod.Name;
            Console.WriteLine);
 
            detect;
        }
 
        /// <summary>
        /// Этот метод вызывается методом <see cref="motitorSensor"/>, 
        /// чтобы сообщить о прохождении транспортного средства 
        /// наблюдателю этого объекта
        /// </summary>
        private void detect
        {
            _observer.vehiclePassed;
        }
 
        /// <summary>
        /// Классы должны реализовывать этот интерфейс, 
        /// чтобы объект <see cref="TrafficSensor"/> мог сообщить им о прохождении 
        /// машин
        /// </summary>
        public interface ITrafficObserver
        {
            /// <summary>
            /// Вызывается тогда, когда <see cref="TrafficSensor"/> фиксирует 
            /// проходящее транспортное средство.
            /// </summary>
            void vehiclePassed;
        }
    }
}
using System;
 
namespace Digital_Patterns.Concurrency.Single_Thread_Execution
{
    /// <summary>
    /// Экземпляры класса <see cref="TrafficSensorController"/> хранят текущее
    /// общее количество машин, прошедших мимо сенсоров движения транспорта,
    /// связанных с экземпляром.
    /// </summary>
    class TrafficSensorController : TrafficSensor.ITrafficObserver
    {
        private Int32 _vehicleCount = 0;
 
        /// <summary>
        /// Этот метод вызывается в том случае, когда сенсор движения
        /// транспорта фиксирует прохождение машины. Он увеличивает 
        /// значение счетчика машин на единицу.
        /// </summary>
        public void vehiclePassed
        {
            lock 
            {
                ++_vehicleCount;
            }
        }
 
        /// <summary>
        /// Сбрасывает счетчик машин в нуль
        /// </summary>
        /// <returns></returns>
        public Int32 GetAndClearCount
        {
            lock 
            {
                Int32 count = _vehicleCount;
                _vehicleCount = 0;
                return count;
            }
        }
    }
}
using System;
using System.Threading;
 
namespace Digital_Patterns.Concurrency.Single_Thread_Execution
{
    /// <summary>
    /// Экземпляры класса <see cref="TrafficTransmitter"/> отвечают за передачу
    /// занчения, определяющего количество машин, проходящих через данное место
    /// дороги за одну минуту.
    /// </summary>
    class TrafficTransmitter
    {
        private TrafficSensorController _conrtoller;
        private Thread _myThread;
 
        public Boolean IsRun { get; set; }
 
        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="conrtoller">От <see cref="TrafficSensorController"/> этот объект
        /// будет получать значение счетчика количества прошедших 
        /// машин</param>
        public TrafficTransmitter
        {
            _conrtoller = conrtoller;
 
            _myThread = new Thread;
            IsRun = true;
            _myThread.Start;
        }
 
        /// <summary>
        /// Передает значение счетчика количества машин, прошедщих 
        /// за промежуток времени
        /// </summary>
        private void Run
        {
            while 
            {
                Thread.Sleep;
                Transmit);
            }
        }
 
        private void Transmit
        {
            //TODO Something
            var msg = System.Reflection.MethodInfo.GetCurrentMethod.Name;
            Console.WriteLine);
        }
    }
}
using System;
using Digital_Patterns.Concurrency.Single_Thread_Execution;
 
namespace Digital_Patterns
{
    class Program
    {
        static void Main
        {
            var controller = new TrafficSensorController;
            var transmitter = new TrafficTransmitter;
 
            Console.WriteLine;
            Console.ReadKey;
 
            var sensor1 = new TrafficSensor;
            var sensor2 = new TrafficSensor;
 
            Console.ReadKey;
 
            sensor1.IsRun = false;
            sensor2.IsRun = false;
            transmitter.IsRun = false;
            Console.WriteLine;
        }
    }
}


Просмотров: 1462


<<< Scheduler
Абстрактная фабрика (шаблон проектирования) >>>