zoukankan      html  css  js  c++  java
  • 29.3 用户模式构造

    29.3.1 易变构造

    当线程通过共享内存互相通信时,调用Volatile.Write来写入最后一个值,调用Volatile.Read来读取第一个值

        public class ThreadsSharingData
        {
            private volatile int flag = 0;
            private int value = 0;
            public void Thread1()
            {
                //注意在将1写入flag之前,必须先将5写入value
                value = 5;
                flag = 1;
            }
            public void Thread2()
            {
                //注意在value必须在读取了flag之后才能读取
                if (flag == 1)
                    Console.WriteLine(value);
            }
        }

     29.3.2 互锁构造

        internal sealed class AsyncCoordinator
        {
            private int m_opCount = 1;
            private int m_statusReported = 0;
            private Action<CoordinatorStatus> m_callback;
            private Timer m_timer;
    
            public void AboutToBegin(int opsToAdd = 1)
            {
                Interlocked.Add(ref m_opCount, opsToAdd);
            }
    
            public void JuseEnded()
            {
                if (Interlocked.Decrement(ref m_opCount) == 0)
                    ReportStatus(CoordinatorStatus.AllDone);
            }
    
            public void AllBegun(Action<CoordinatorStatus> callback, int timeout = Timeout.Infinite)
            {
                m_callback = callback;
                if (timeout != Timeout.Infinite)
                    m_timer = new Timer(TimeExpired, null, timeout, Timeout.Infinite);
                JuseEnded();
            }
    
            private void TimeExpired(object o)
            {
                ReportStatus(CoordinatorStatus.Timeout);
                ReportStatus(CoordinatorStatus.Cancel);
            }
    
            private void ReportStatus(CoordinatorStatus status)
            {
                if (Interlocked.Exchange(ref m_statusReported, 1) == 0)
                    m_callback(status);
            }
    
            public enum CoordinatorStatus
            {
                AllDone, Timeout, Cancel
            }
        }

     29.3.3 实现简单的自旋锁

        class Program
        {
            private static SimpleSpinLock ssl = new SimpleSpinLock();
            static void Main()
            {
                ssl.Enter();
                //一次只有一个线程才能进入这里访问资源
                ssl.Leave();
    
                Console.ReadKey();
            }
        }
        internal struct SimpleSpinLock
        {
            private int m_resourceInuse;    //0=false,1=true
            public void Enter()
            {
                while (true)
                {
                    //总是将资源设置为正在使用
                    //只有未使用变成正在使用才会返回
                    if (Interlocked.Exchange(ref m_resourceInuse, 1) == 0)
                        return;
                    //添加黑科技
                }
            }
            public void Leave()
            {
                Volatile.Write(ref m_resourceInuse, 0);
            }
        }

    29.3.4 Interlocked anything

            delegate int Morpher<TResult, TArgument>(int startValue, TArgument argument, out TResult morphResult);
    
            private static TResult Morph<TResult, TArgument>(ref int target, TArgument argument, Morpher<TResult, TArgument> morpher)
            {
                TResult morphResult;
                int currentVal = target, startVal, desiredVal;
                do
                {
                    startVal = currentVal;
                    desiredVal = morpher(startVal, argument, out morphResult);
                    currentVal = Interlocked.CompareExchange(ref target, desiredVal, startVal);
    
                }
                while (startVal != currentVal);
                return morphResult;
            }
    
            private static int Maximun(ref int target, int value)
            {
                int currentVal = target, startVal, desiredVal;
                //不要在循环中访问目标target,除非想要改变它时另一个线程也在动它
                do
                {
                    //记录这一次循环的起始值startVal
                    startVal = currentVal;
                    //基于startVal和value计算desiredVal
                    desiredVal = Math.Max(startVal, value);
                    //注意:线程在这里可能被“抢占”,所以以下代码不是原子性的
                    //if (target == startVal) target = desiredVal;
                    //使用原子性的方法,返回在target在(可能)被方法修改之前的值
                    currentVal = Interlocked.CompareExchange(ref target, desiredVal, startVal);
                }
                //如果target的值在这一次循环迭代中被其它线程改变,就重复
                while (startVal != currentVal);
                return desiredVal;
            }
  • 相关阅读:
    iOSraywenderlich翻译使用MapKit叠加图层
    IOSTableView学习V2.0
    html的<input>标签常用属性
    SQLSqlServer中decimal(numeric )、float 和 real 数据类型的区别[转]
    PhoneGapV1.0
    IOSPlistV1.0
    IOS使用 UITableView 创建表格应用演练(1)——一个简单的表格应用V3.0
    IOSTableView学习V4.0
    IOS从plist文件加载并显示数据
    学习思路
  • 原文地址:https://www.cnblogs.com/kikyoqiang/p/10211988.html
Copyright © 2011-2022 走看看