I am experimenting with locks that do not require atomic instructions. Peterson's algorithm seemed the easiest place to start. However, with enough iterations, something goes wrong.
the code:
public class Program { private static volatile int _i = 0; public static void Main(string[] args) { for (int i = 0; i < 1000; i++) { RunTest(); } Console.Read(); } private static void RunTest() { _i = 0; var lockType = new PetersonLock(); var t1 = new Thread(() => Inc(0, lockType)); var t2 = new Thread(() => Inc(1, lockType)); t1.Start(); t2.Start(); t1.Join(); t2.Join(); Console.WriteLine(_i); } private static void Inc(int pid, ILock lockType) { try { for (int i = 0; i < 1000000; i++) { lockType.Request(pid); _i++; lockType.Release(pid); } } catch (Exception ex) { Console.WriteLine(ex); } } } public interface ILock { void Request(int pid); void Release(int pid); } public class NoLock : ILock { public void Request(int pid) { } public void Release(int pid) { } } public class StandardLock : ILock { private object _sync = new object(); public void Request(int pid) { Monitor.Enter(_sync); } public void Release(int pid) { Monitor.Exit(_sync); } } public class PetersonLock : ILock { private volatile bool[] _wantsCs = new bool[2]; private volatile int _turn; public void Request(int pid) { int j = pid == 1 ? 0 : 1; _wantsCs[pid] = true; _turn = j; while (_wantsCs[j] && _turn == j) { Thread.Sleep(0); } } public void Release(int pid) { _wantsCs[pid] = false; } }
When I run this, I sequentially get <2,000,000. What happens?
multithreading c # locking
Condition racer
source share