• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#语言的多线程编程,完全是本科OS里的知识

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

Thread类的参数就是参数指针,可以传入一个无参的函数。

如果要传入带参数的函数,先new一个ParameterizedThreadStart委托实例,带参数的函数名作为它的参数。带参数的函数必须且只能有一个object参数。参考下面的

ConterWithParam(object param)

 

static int iCnt = 0;
        static readonly int N = 10000;

        static void Main(string[] args)
        {
            Thread[] thrs = new Thread[N];
            for (int i = 0; i < N; i++)
            {
                thrs[i] = new Thread(Counter);
                thrs[i].Start();               
            }
            for (int i = 0; i < N; i++)
            {              
                thrs[i].Join();
            }
            Console.WriteLine(iCnt);

            iCnt = 0;

            ParameterizedThreadStart[] thrsp = new ParameterizedThreadStart[N];
            object param = 2;
            for (int i = 0; i < N; i++)
            {
                thrsp[i] = new ParameterizedThreadStart(ConterWithParam);
                thrs[i] = new Thread(thrsp[i]);
                thrs[i].Start(param);
            }
            for (int i = 0; i < N; i++)
            {
                //当NewThread调用Join方法的时候,MainThread就被停止执行,直到NewThread线程执行完毕
                thrs[i].Join();
            }
            Console.WriteLine(iCnt);
        }

        static void Counter()
        {
            Thread.Sleep(100);
            iCnt++;
            //Console.WriteLine("finish iCnt++,now iCnt is " + iCnt);            
        }

        static void ConterWithParam(object param)
        {
            Thread.Sleep(100);
            int i = (int)param;
            iCnt += i;
            //Console.WriteLine("finish iCnt+"+i+",now iCnt is " + iCnt);     
        }

 

该例子输出结果

2)互斥信号灯mutex

第一节的结果是不是有点奇怪。明明加了10000次,结果却是9550.

带参数的那个例子,一次加2,加10000次,应该是20000才对。结果却是19678.

这是因为对全局变量的访问iCnt出现了冲突。比如两个线程同时取到了iCnt=0时的值,同时执行了i++,那么iCnt的最后状态肯定是1,而不是会2。为了让iCnt得到正确的值。

我们引入互斥信号灯。

static int iCnt = 0;
        static readonly int N = 10000;
        static Mutex mut = new Mutex();

        static void Main(string[] args)
        {
            Thread[] thrs = new Thread[N];
            for (int i = 0; i < N; i++)
            {
                thrs[i] = new Thread(Counter);
                thrs[i].Start();               
            }
            for (int i = 0; i < N; i++)
            {              
                thrs[i].Join();
            }
            Console.WriteLine(iCnt);

            iCnt = 0;

            ParameterizedThreadStart[] thrsp = new ParameterizedThreadStart[N];
            object param = 2;
            for (int i = 0; i < N; i++)
            {
                thrsp[i] = new ParameterizedThreadStart(ConterWithParam);
                thrs[i] = new Thread(thrsp[i]);
                thrs[i].Start(param);
            }
            for (int i = 0; i < N; i++)
            {
                //当NewThread调用Join方法的时候,MainThread就被停止执行,直到NewThread线程执行完毕
                thrs[i].Join();
            }
            Console.WriteLine(iCnt);
        }

        static void Counter()
        {
            Thread.Sleep(10);
            //
            mut.WaitOne();            
            iCnt++;
            //释放
            mut.ReleaseMutex();
            //Console.WriteLine("finish iCnt++,now iCnt is " + iCnt);            
        }

        static void ConterWithParam(object param)
        {
            Thread.Sleep(10);
            //锁住
            mut.WaitOne();            
            int i = (int)param;
            iCnt += i;
            //释放
            mut.ReleaseMutex();
            //Console.WriteLine("finish iCnt+"+i+",now iCnt is " + iCnt);     
        }

 

本次执行结果

3) 同步信号灯Semaphore

用最经典的生产者-消费者来解释。

static Semaphore sem = new Semaphore(0, 1);
        static Semaphore sem2 = new Semaphore(0, 5);

        static void Main(string[] args)
        {
            Console.WriteLine("消费者等生产者生产一个item");
            Thread thConsumer = new Thread(Consume);
            thConsumer.Start();
            Thread thProductor = new Thread(Product);
            thProductor.Start();

            thConsumer.Join();
            thProductor.Join();
            Console.WriteLine(".............................");

            Console.WriteLine("多并发的例子.....");
            for (int i = 0; i < 10; i++)
            {
                Thread t1 = new Thread(Consume2);
                t1.Start();
                Thread t2 = new Thread(Product2);
                t2.Start();
            }//end for
            

        }


        static void Product()
        {
            Thread.Sleep(2000);
            Console.WriteLine("Product an item...");
            sem.Release();
        }

        static void Consume()
        {
            Thread.Sleep(1000);
            Console.WriteLine("Consumer is waiting an item...");
            sem.WaitOne();
            Console.WriteLine("Consumer get an item...");
        }



        static void Product2()
        {
            Thread.Sleep(1000);
            Console.WriteLine("Product an item...");
            sem2.Release();
        }

        static void Consume2()
        {
            Thread.Sleep(1000);
            Console.WriteLine("Consumer is waiting an item...");
            sem2.WaitOne();
            Console.WriteLine("Consumer get an item...");
        }

 

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
A*算法的C++实现发布时间:2022-07-13
下一篇:
c#.net获取时间日期生成自动文件名格式发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap