N
NikSoft
В моем последнем фрагменте была допущена некорректность. В критическую секцию надо включить предложение
Проблема в том, что n потоков могут выполнить вышеуказанное предложение перед тем, как образовать очередь в критическую секцию. Для этих n потоков значение _instanceNumber
будет равно нулю и следовательно будет создано n обьектов типа SerialPort, что легко проверяется следующим кодом.
Обращение к типу SerialPort осуществляется так.
Корректный вариант приводится ниже.
Код:
if (_instanceNumber > 1)
{
Console.WriteLine(String.Format("No more than 2 serial ports allowed"));
}
Проблема в том, что n потоков могут выполнить вышеуказанное предложение перед тем, как образовать очередь в критическую секцию. Для этих n потоков значение _instanceNumber
будет равно нулю и следовательно будет создано n обьектов типа SerialPort, что легко проверяется следующим кодом.
Код:
using System;
using System.Threading;
namespace SerialPorts
{
sealed class SerialPort
{
static volatile int _instanceNumber;
SerialPort() { }
public static SerialPort NextInstance()
{
SerialPort serialPort = null;
if (_instanceNumber > 1)
{
Console.WriteLine(String.Format("No more than 2 serial ports allowed"));
}
else
{
lock (typeof(SerialPort))
{
_instanceNumber++;
Console.WriteLine(String.Format("Starting to work with serial port {0}", _instanceNumber));
serialPort = new SerialPort();
Thread.Sleep(500);
}
}
return serialPort;
}
}
}
Обращение к типу SerialPort осуществляется так.
Код:
using System;
using System.Threading;
namespace SerialPorts
{
class Program
{
static void Main(string[] args)
{
ThreadStart worker1 = new ThreadStart(WorkerThreadMethod);
ThreadStart worker2 = new ThreadStart(WorkerThreadMethod);
ThreadStart worker3 = new ThreadStart(WorkerThreadMethod);
Thread t1 = new Thread(worker1);
Thread t2 = new Thread(worker2);
Thread t3 = new Thread(worker3);
t1.Start();
t2.Start();
t3.Start();
Console.ReadLine();
}
public static void WorkerThreadMethod()
{
SerialPort serialPort;
serialPort = SerialPort.NextInstance();
}
}
}
Корректный вариант приводится ниже.
Код:
using System;
using System.Threading;
namespace SerialPorts
{
sealed class SerialPort
{
static volatile int _instanceNumber;
SerialPort() { }
public static SerialPort NextInstance()
{
SerialPort serialPort = null;
lock (typeof(SerialPort))
{
if (_instanceNumber > 1)
{
Console.WriteLine(String.Format("No more than 2 serial ports allowed"));
}
else
{
_instanceNumber++;
Console.WriteLine(String.Format("Starting to work with serial port {0}", _instanceNumber));
serialPort = new SerialPort();
}
}
return serialPort;
}
}
}