Implementing a synchronization algorithm in C #

I am trying to implement a synchronization algorithm in C # without success.

Why is the following code safe?

using System;
using System.Threading;

namespace SoftwareLockTest
{
    class Program
    {
        private static volatile bool _isLocked1 = false;
        private static volatile bool _isLocked2 = false;
        private static volatile int _count = 0;

        static void Main(string[] args)
        {
            Thread thread2 = new Thread(Thread2Work);
            thread2.Start();

            Thread1Work();
        }

        public static void Thread1Work()
        {
            while (true)
            {
                _isLocked1 = true;

                while (_isLocked2)
                {
                    _isLocked1 = false;
                    while (_isLocked2) ;
                    _isLocked1 = true;
                }

                CriticalSection();
                _isLocked1 = false;
            }
        }

        public static void Thread2Work()
        {
            while (true)
            {
                _isLocked2 = true;

                while (_isLocked1)
                {
                    _isLocked2 = false;
                    while (_isLocked1) ;
                    _isLocked2 = true;
                }

                CriticalSection();
                _isLocked2 = false;
            }
        }

        private static void CriticalSection()
        {
            if (_count != 0)
            {
                Console.WriteLine("NOT THREAD SAFE 1");
                _count = 0;
            }

            _count++;

            if (_count != 1)
            {
                Console.WriteLine("NOT THREAD SAFE 2");
            }

            _count--;

            if (_count != 0)
            {
                Console.WriteLine("NOT THREAD SAFE 3");
            }
        }
    }
}
+3
source share
6 answers

The problem is that the record followed by the read can be reordered (even with "volatile"). You need to call Thread.MemoryBarrier (); before four while loops (_isLockedX).

Please read http://www.albahari.com/threading/part4.aspx for an explanation of memory barriers and instability.

, , , .

+6

. , , . , , - . , .

, . "" , , . , . , , concurrency, 5 , .

+5

, , , , lock/Monitor, Interlocked (.Increment)/ (.Decrement)/test (.CompareExchange). , volatile , ++/-- .

, , lock, . - ", ", " ".

+2

, , , ... , , volatile, , , , .

, , : " , , , ". ( , MSDN , , ).

, , , . , , , , "" ... ( , )

+2

, codeguru ... , , , .

, . x86 SC. .

, -:

thread1:

WRITE _isLocked1, 1
READ _isLocked2
(skip the while loop)
critical section
WRITE _isLocked1, 0

thread2:

WRITE _isLocked2, 1
READ _isLocked1
(skip the while loop)
critical section
WRITE _isLocked2, 0

, thread1 , 2, , ( 1, 0). 2 1 . , , - , , 1 thread2, , ( ).

AMD, 2, 7.2, , x86.

+2

lock?

lock (_anyInstantiatedObject)
{
    CriticalSection();
}

Thus, you rely on the OS to ensure that no other thread enters the critical section at the same time.

0
source

Source: https://habr.com/ru/post/1727051/


All Articles