zoukankan      html  css  js  c++  java
  • Semaphore的应用

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    
    namespace SynchronizationContext
    {
        internal interface IQueueReader<T> : IDisposable
        {
            T Dequeue();
            void ReleaseReader();
        }
    
        internal interface IQueueWriter<T> : IDisposable
        {
            void Enqueue(T data);
        }
    
        internal class BlockingQueue<T> : IQueueReader<T>, IQueueWriter<T>, IDisposable
        {
            // use a .NET queue to store the data
            private Queue<T> mQueue = new Queue<T>();
            // create a semaphore that contains the items in the queue as resources.
            // initialize the semaphore to zero available resources (empty queue).
            private Semaphore mSemaphore = new Semaphore(0, int.MaxValue);
            // a event that gets triggered when the reader thread is exiting
            private ManualResetEvent mKillThread = new ManualResetEvent(false);
            // wait handles that are used to unblock a Dequeue operation.
            // Either when there is an item in the queue
            // or when the reader thread is exiting.
            private WaitHandle[] mWaitHandles;
    
            public BlockingQueue()
            {
                mWaitHandles = new WaitHandle[2] { mSemaphore, mKillThread };
            }
            public void Enqueue(T data)
            {
                lock (mQueue)
                {
                    mQueue.Enqueue(data);
                    //mQueue.Enqueue(data);//test
                }
                // add an available resource to the semaphore,
                // because we just put an item
                // into the queue.
                mSemaphore.Release();
                //mSemaphore.Release(2);//test
            }
    
            public T Dequeue()
            {
                // wait until there is an item in the queue
                WaitHandle.WaitAny(mWaitHandles);
                lock (mQueue)
                {
                    if (mQueue.Count > 0)
                        return mQueue.Dequeue();
                }
                return default(T);
            }
    
            public void ReleaseReader()
            {
                mKillThread.Set();
            }
    
    
            void IDisposable.Dispose()
            {
                if (mSemaphore != null)
                {
                    mSemaphore.Close();
                    mQueue.Clear();
                    mSemaphore = null;
                }
            }
        }
    }

    出处:http://www.codeproject.com/Articles/32113/Understanding-SynchronizationContext-Part-II

    namespace SynchronizationContext
    {
        class Program
        {
            static void Main(string[] args)
            {
                BlockingQueue<string> bq = new BlockingQueue<string>();
                //线程t1向bq中延迟插入数据
                Thread t1 = new Thread(() => { Thread.Sleep(4000); bq.Enqueue("test"); });
                t1.Start();
                //在t1将test加入到bq前,这个操作被阻塞4s左右
                string d = bq.Dequeue();
                Console.WriteLine("d:" + d);
                //Semaphore使用保证了队列中没有东西的时候出出队列的操作都是阻塞的
                string d2 = bq.Dequeue();
                Console.WriteLine("d2:" + d2);
                string d3 = bq.Dequeue();
                Console.WriteLine("d3:" + d3);
            }
        }
    }
    作者:zhanjindong
    出处:http://www.cnblogs.com/zhanjindong
    个人博客:http://zhanjindong.com
    关于:一个程序员而已
    说明:目前的技术水平有限,博客定位于学习心得和总结。
  • 相关阅读:
    鹅厂女专家:用“爱折腾”实现跨界之美
    基于腾讯云的视频聊天研究
    iOS微信内存监控
    2017年数据库技术盘点
    如何做好游戏内实时语音体验
    腾讯云微计算实践:从Serverless说起,谈谈边缘计算的未来
    使用腾讯云“自定义监控”监控GPU使用率
    如何在Python中从零开始实现随机森林
    DataGridView 设置某个列为只能为数字
    Ieditor
  • 原文地址:https://www.cnblogs.com/zhanjindong/p/2978375.html
Copyright © 2011-2022 走看看