Semaphore和SWaitHandle

Semaphore:其实.NET中的信号量(Semaphore)是操作系统维持的一个整数。当整数位0时。其他线程无法进入。当整数大于0时,线程可以进入。每当一个线程进入,整数-1,线程退出后整数+1。整数不能超过信号量的最大请求数。信号量在初始化的时候可以指定这个整数的初始值。

WaitHandle:这个类的,需要为每个线程创建一个WaitHandle对象并把它们放在一个数组中,然后用WaitHandle类中的WaitAll方法来等待这些 WaitHandle被调用Set方法。主意:当waihandle在线程池中的,数组的元素个数超过(>)64时,就会报异常(System.NotSupportedException: WaitHandle 的数目必须少于或等于 64 个)

看一个waitHandle的例子

class other
    {
        static void Main(string[] args)
        {
            Random randomGenerator = new Random();
            AutoResetEvent[] resets=new AutoResetEvent[5];

            for (int i = 0; i < 5; i++)
            {
                resets[i] = new AutoResetEvent(false);
                int wTime = randomGenerator.Next(10)+1;

                worker w = new worker(wTime, resets[i]);

                Thread thrd1 = new Thread(new ThreadStart(w.work));
                thrd1.Start();  
            }
            WaitHandle.WaitAll(resets);//等待所有AutoResetEvent线程全部完成,再继续
            Console.WriteLine("ALL worker done - main exiting.");
        }

    }

    public class worker
    {
        public string name;
        public int wTime;
        public AutoResetEvent mEvent;

        public worker(int w, AutoResetEvent m)
        {
            name = w.ToString();
            wTime = w * 1000;
            mEvent = m;
        }

        public void work()
        {
            Console.WriteLine(name + " worker thread waiting for " + wTime + "....");
            Thread.Sleep(wTime);
            Console.WriteLine(name + " worker thread back...");
            mEvent.Set();//释放信号
        }
    }


项目中的例子

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using Citi.Equity.QSDBScheduler.Common;
using System.Threading;
using System.IO;
using System.Data;
using EQTG.Database;

namespace Citi.Equity.ClientReport.VOLDBDaily
{
    internal class VolCacheCalculator
    {
        private string asOfDate = string.Empty;
        private static object syncObj = new object();
        private IDbConnection connOutter = null;
        private static string sqlTemplate = "select o.id,o.usym,o.pc,o.strike,o.expire,o.type,p.date,p.bidimp,p.askimp from VOLDB_VOL_OPTIONS o inner join VOLDB_VOL_PRICES p on o.id=p.id where o.usym = '{0}' and o.type = 2 and p.date={1};";

        internal VolCacheCalculator(string asOfDate, IDbConnection conn)
        {
            this.asOfDate = asOfDate;
            this.connOutter = conn;

            DBUtil.setQueryTimeout(3600);
        }

        internal List<VolResult> Calculate()
        {
            List<VolResult> result = new List<VolResult>();
            List<UndEntity> tckList = null;

            try
            {
                tckList = GetTickerList(connOutter);
            }
            catch (Exception ex)
            {
                ourLogger.Error("Failed to get tck list", ex);
            }

            if (tckList == null || tckList.Count == 0)
                return result;

            if (File.Exists("Complete.txt"))
            {
                lock (syncObj)
                {
                    File.Delete("Complete.txt");
                }
            }

            SuperWaitHandle swh = new SuperWaitHandle();
            System.Threading.Semaphore resource = new System.Threading.Semaphore(20, 20);//设置初始信号量为20
            foreach (UndEntity tck in tckList)
            {
                StateWrap wrap = new StateWrap();
                wrap.TCK = tck;
                wrap.WaitEvent = swh.CreateWaitEvent();//增加一个AutoResetEvent到list中

                ThreadPool.QueueUserWorkItem(delegate(object state)
                {
                    IDbConnection conn = null;
                    StateWrap dataPack = (StateWrap)state;
                    string symbol = dataPack.TCK.Symbol;
                    int eod = dataPack.TCK.Eod;
                    double spot = dataPack.TCK.Spot;
                    try
                    {
                        resource.WaitOne();//占有一个信号量,如果这里是manualEventRestwaitone便会等待,Semaphore初始值是20,如果第21个就会等待

                        conn = MyDBUtil.CreateConnection(connOutter.ConnectionString);

                        string sql = string.Format(sqlTemplate, symbol, eod);

                        // force to execute GC
                        GC.Collect();
                        GC.WaitForPendingFinalizers();

                        DataSet ds = DBUtil.ExecuteDBQuery(sql, conn);
                        DataTable dtSource = ds.Tables[0];
                        List<VolResult> volCacheResult = BuildVolSurface(symbol, eod, spot, dtSource);

                        if (volCacheResult != null)
                        {
                            lock (syncObj)
                            {
                                result.AddRange(volCacheResult);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        ourLogger.Error("Failed when build vol for " + symbol, ex);
                    }
                    finally
                    {
                        lock (syncObj)
                        {
                            using (StreamWriter sw = new StreamWriter(@"Complete.txt", true))
                            {
                                sw.WriteLine(symbol);
                            }
                        }

                        if (conn != null && conn.State != ConnectionState.Closed)
                        {
                            conn.Close();
                            conn = null;
                        }

                        resource.Release();//释放一个信号量(针对的是Semaphore)
                        dataPack.WaitEvent.Set();//释放Set命令(针对 waitHandle)

                    }
                }, wrap);
            }

            swh.WaitAll();//等待所有线程全部计算完毕,再回到Main函数 

            return result;
        }

        private List<UndEntity> GetTickerList(IDbConnection conn)
        {
            List<UndEntity> list = new List<UndEntity>();
            return list;
        }


        internal class UndEntity
        {
            public string Symbol { get; set; }
            public int Eod { get; set; }
            public double Spot { get; set; }
        }

        internal class VolResult
        {
            public string Symbol { get; set; }
            public int Eod { get; set; }
            public double Moneyness { get; set; }
            public string Term { get; set; }
            public double AvgImp { get; set; }
            public double BA_spread { get; set; }
            public double pc_spread { get; set; }
        }

        internal class StateWrap
        {
            public UndEntity TCK;
            public AutoResetEvent WaitEvent;
        }

        internal class SuperWaitHandle
        {
            List<AutoResetEvent> list = new List<AutoResetEvent>();
            public AutoResetEvent CreateWaitEvent()
            {
                AutoResetEvent autoEvent = null;
                lock (this)
                {
                    do
                    {
                        autoEvent = new AutoResetEvent(false);
                    }
                    while (autoEvent == null || list.Contains(autoEvent));

                    list.Add(autoEvent);
                }
                return autoEvent;
            }

            public void Reset()
            {
                list = new List<AutoResetEvent>();
            }

            public bool WaitAll()
            {
                List<AutoResetEvent> temp = new List<AutoResetEvent>(64);
                for (int i = 0; i < list.Count; i++)
                {
                    if (temp.Count == 64)
                        temp = new List<AutoResetEvent>(64);
                    if (temp.Count < 64)
                    {
                        temp.Add(list[i]);
                        if (temp.Count == 64 || temp.Contains(list.LastOrDefault()))
                        {
                            WaitHandle.WaitAll(temp.ToArray());//开64个AutoResetEvent的线程组,waitall阻止线程,直到所有线程都收到信号
                        }
                    }
                }
                return true;

            }
        }

        internal class MyDBUtil
        {
            public static IDbConnection CreateConnection(string connectionString)
            {
                IDbConnection myDbCnn = null;

                if (myDbCnn == null && connectionString != null)
                {
                    myDbCnn = DBSelector.Factory.Connection(connectionString);
                }
                if (myDbCnn.State == ConnectionState.Closed)
                {
                    myDbCnn = DBSelector.Factory.Connection(connectionString);
                }
                if (myDbCnn.State == ConnectionState.Closed)
                {
                    myDbCnn.Open();
                }
                return myDbCnn;
            }
        }
    }
}


http://www.cnblogs.com/LoveJenny/tag/%E6%B7%B1%E5%85%A5%E6%B5%85%E5%87%BA/

http://www.cnblogs.com/nokiaguy/category/144877.html

http://kb.cnblogs.com/page/42528/

http://blog.csdn.net/yl2isoft/article/details/11879625


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值