首页 > 代码库 > C# 语言的多线程编程,完全是本科OS里的知识

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

 基本知识,无参数Thread和带参数的Thread

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...");        }

 

 

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