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

时间: 2024-11-05 16:35:57

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

java多线程编程(1) 线程的基本知识

在前面研究过多线程与进程的区别. 这里在稍微总结一下: 进程:程序动态的一次执行过程. 线程:可以只是程序员的一部分的执行过程 每个进程有多个线程组成,在java程序中,至少两个线程一个是垃圾回收线程和main线程. 线程占有的资源更少,早java中就是每个线程都有自己的工作区,就是有自己独立的栈空间.多个线程共享一些内存资源,堆是共享的. 多线程的力度小,并发度高,这样系统的吞吐量就很大,只有好处吗?调度和执行线程是需要资源的,就是像是数据库中的索引和数据库中的锁一个道理,并发会带来什么问题呢

Rust语言的多线程编程

Concurrency并发 在计算机科学上,并发Concurrency 和并行 parallelism是非常重要的话题,也是软件产业一个热门的话题.电脑有了越来越多的的核,但喝多程序员没有准备好充分利用它们. Rust的内存安全特性也应用于并发.Rust程序必须内存安全,没有数据竞争.Rust的类型系统 很胜任这工作,很容易让你理解在编译时的并行代码. 在谈论Rust并发特色之前,了解一些东西很重要:Rust是一门足够低级的语言,所有这些都由标准库提供,而不是语言本身.这意味着如果你你不喜欢Ru

多线程编程 之 入门篇

<pre name="code" class="cpp">自己第一次涉及c语言的多线程编程,实属入门了解级别的:之前只做过java的Runnable的多线程编程.本次我们可以把屏幕看成是一个资源,这个资源被两个线程所共用, /* #include <iostream> #include <windows.h> using namespace std; DWORD WINAPI Fun(LPVOID lpParamter) { wh

C语言多线程编程

原文:C语言多线程编程 注:本文内容来源于互联网,感谢作者整理! Windows的多线程编程 c语言 在Windows的多线程编程中,创建线程的函数主要有CreateThread和_beginthread(及_beginthreadex). CreateThread 和 ExitThread    使用API函数CreateThread创建线程时,其中的线程函数原型:  DWORD WINAPI ThreadProc(LPVOID lpParameter);在线程函数返回后,其返回值用作调用Ex

C语言中的多线程编程

很久很久以前,我对C语言的了解并不是很多,我最早听说多线程编程是用Java,其实C语言也有多线程编程,而且更为简单.方便.强大.下面就让我们简单领略一下Unix C语言环境下的多线程编程吧! 下面先看一个简单的单线程程序: /* 06.3.6 Sghello.c Hello,world -- Single Thread */ #include #define NUM 6 int main() { void print_msg(char*); print_msg("hello,"); p

C语言使用pthread多线程编程(windows系统)二

我们进行多线程编程,可以有多种选择,可以使用WindowsAPI,如果你在使用GTK,也可以使用GTK实现了的线程库,如果你想让你的程序有更多的移植性你最好是选择POSIX中的Pthread函数库,我的程序是在Linux下写的,所以我使用了Pthread库(是不是很伤心,我知道有不少人期待的是WindowsAPI的,好吧,有机会以后再讲那个,现在先把这一系列专题写完 ^_^)如果你用的是LINUX/UNIX/MacOSX,那么我们已经可以开始了,如果你用的是WINDOWS,那么你需要从网站上下载

linux下C语言多线程编程实例

学东西,往往实例才是最让人感兴趣的,老是学基础理论,不动手,感觉没有成就感,呵呵.下面先来一个实例.我们通过创建两个线程来实现对一个数的递加.或许这个实例没有实际运用的价值,但是稍微改动一下,我们就可以用到其他地方去拉.下面是我们的代码: /*thread_example.c : c multiple thread programming in linux *author : falcon *E-mail : [email protected] */ #include <pthread.h>

浅谈C语言嵌入式系统编程注意事项

C语言嵌入式系统编程注意事项之背景篇 本文的讨论主要围绕以通用处理器为中心的协议处理模块进行,因为它更多地牵涉到具体的C语言编程技巧 不同于一般形式的软件编程,嵌入式系统编程建立在特定的硬件平台上,势必要求其编程语言具备较强的硬件直接操作能力.无疑,汇编语言具备这样的特质.但是,归因于汇编语言开发过程的复杂性,它并不是嵌入式系统开发的一般选择.而与之相比,C语言--一种"高级的低级"语言,则成为嵌入式系统开发的最佳选择.笔者在嵌入式系统项目的开发过程中,一次又一次感受到C语言的精妙,沉

C语言嵌入式系统编程修炼

C语言嵌入式系统编程修炼 ?? 2008-08-19 作者:宋宝华 来源:天极网 ?? C语言嵌入式系统编程修炼之背景篇 本文的讨论主要围绕以通用处理器为中心的协议处理模块进行,因为它更多地牵涉到具体的C语言编程技巧 不同于一般形式的软件编程,嵌入式系统编程建立在特定的硬件平台上,势必要求其编程语言具备较强的硬件直接操作能力.无疑,汇编语言具备这样的特质.但是,归因于汇编语言开发过程的复杂性,它并不是嵌入式系统开发的一般选择.而与之相比,C语言--一种"高级的低级"语言,则成为嵌入式系