создание синхронизированного массива, который реализует методы чтения \ записи - PullRequest
1 голос
/ 21 апреля 2019

У меня есть класс с полями: массив сообщений и текущее количество сообщений, а также методы read \ write.

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

Я хочу сделать этот класс синхронизированным, чтобы он позволял потокам записывать и читать (когда массив пуст, я хочу, чтобы поток ожидал, пока будет что-то прочитать) от него и предотвращать гонки данных.

Я сделал этот класс, который реализует:

   class SynchronizedDATAStructure : DATAStructure
{
    private Mutex mutexR = new Mutex();
    private Mutex mutexW = new Mutex();
    private Semaphore semaphore = new Semaphore(0, int.MaxValue);
    private Semaphore semaphore2 = new Semaphore(1, 1);

    public override void Write(Message msg)
    {
        mutexW.WaitOne(); // allows only one thread each time to write
        semaphore2.WaitOne(); // checks if nobody is reading 
        base.Write(msg); // writing
        semaphore.Release(); // counts number of messages
        semaphore2.Release(); // finish to write
        mutexW.ReleaseMutex(); // finish the function
    }

    public override Message Read()
    {
        mutexR.WaitOne(); // allows only one thread each time to read
        semaphore.WaitOne();  // checks if there  are messages 
        semaphore2.WaitOne(); // checks if nobody is writing 
        Message msg1 = base.Read(); // reading
        semaphore2.Release(); // finish to read
        mutexR.ReleaseMutex(); // finish the function
        return msg1; // returns the messge
    }

Когда потоки начинают писать \ читать, я получаю outOfBounds через некоторое время, когда поток пытается читать из пустого массива.

1 Ответ

1 голос
/ 21 апреля 2019

Вы можете сделать свой код намного проще, используя Monitor:

class SynchronizedDATAStructure : DATAStructure
{
    private readonly object syncRoot = new object();

    public int MessageCount { get; private set; }

    public override void Write(Message msg)
    {
        lock (syncRoot)
        {
            base.Write(msg);
            MessageCount++;

            Monitor.Pulse(syncRoot);
        }
    }

    public override Message Read()
    {
        lock (syncRoot)
        {
            while (MessageCount <= 0)
            {
                Monitor.Wait(syncRoot);
            }

            MessageCount--;
            return base.Read();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...