千家信息网

C#怎么实现CSP并发模型

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要介绍"C#怎么实现CSP并发模型",在日常操作中,相信很多人在C#怎么实现CSP并发模型问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"C#怎么实现CSP并发
千家信息网最后更新 2026年11月01日C#怎么实现CSP并发模型

这篇文章主要介绍"C#怎么实现CSP并发模型",在日常操作中,相信很多人在C#怎么实现CSP并发模型问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"C#怎么实现CSP并发模型"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    CSP(Communicating sequential processes)

    这东西我一开始以为很简单,后面差了资料发现它独树一帜,自己是一门语言,也是一套理论。这边我不深入的对它做过多的见解,我怕耽误大家=_=,大家可以看看wiki。

    wiki:https://en.wikipedia.org/wiki/Communicating_sequential_processes

    我们从Go的角度对它进行一些分析,摘抄一段概要:

    "用于描述两个独立的并发实体通过共享的通讯 channel(管道)进行通信的并发模型。 CSP中channel是第一类对象,它不关注发送消息的实体,而关注与发送消息时使用的channel。"

    好了,单独写出 CSP 是为了让大家了解这是一套独立于语言的东西,大家有兴趣可以查看wiki和搜索一些其它资料。

    在Go中的CSP

    Channel(通道)

    Goroutine(不知道怎么翻译,大家可以理解成一个"工作者",不是工作者线程。本质是实现了协程。)

    协程(提升并发的利器)

    大家都很明白线程能做什么,但协程是个什么东西?比起线程又如何呢?

    线程

    我们重新思考一些东西。

    CPU:核心、超线程

    OS:线程

    编程语言:线程池

    这边不做细讲,只是大概点到一下。

    我们所做的任何计算都要经由CPU计算,而CPU的核数直接决定了我们能给CPU执行几件事情。

    我们现在所常用的OS内部都有一个轮询,用时间片的形式来分配任何轮流使用CPU执行计算,线程就是这些任务的载体。

    这块的概念非常庞大(还有牵扯到,什么是并发,什么事并行),本文的重点不是这些,大家有兴趣后面可以单独开一篇文章来解释这块的内容。

    回归本文,现在我们知道线程是操作系统级别用来共享CPU的一种技术实现,多线程编程早在各大语言遍地开花,被用的惟妙惟肖,百花齐放。

    那么为什么需要协程呢?

    线程的开销

    这块又是一个大知识点,这边也不多做介绍。

    大家只要明白,线程并不是廉价的,一个线程的创立有至少两点的开销

    • 内存

    • 调度器压力(线程上下文切换等)

    线程是可以持有逻辑数据的(比如,HttpContext.Current,等对象)所以必定是占用内存的(至于占用了多少内存不同的语言和OS不一样)

    如果一个CPU是4核的,同时就只能处理4件任务,一个OS的线程越多他们轮训一整圈所耗的时间就更长。而每次调度线程时都需要复制当前线程上下文的状态,再去读取准备调度线程上下文的状态。

    这边可以看到最后一点,有时候多线程反而会比单线程更加的慢,所以多线程提升性能本质上其实是假的。多线程并不会提升程序性能。

    我知道这边肯定有人会心存疑问,绝大数的人都说用多线程来提升性能,为什么这边说多线程会比单线程慢?

    我们这边想一下:PHP 和 NodeJS,PHP默认不支持多线程,NodeJS采用单线程事件轮询,他们的效率比拥有多线程的语言低吗?并不会。

    多线程之所以快是因为作弊,别人一个人干的事情你叫两个人去干当然会比单线程快。这也有非常大的限制,多线程所执行的东西尽可能避免共享,不然你的效率还是可能不如单线程。

    这边说的有点跑题,这块的内容实在太大,大家只要知道,线程即使不昂贵也绝不廉价。

    针对这个问题,各大语言都推出了一个叫做线程池的技术,我申请一批线程,持有他,等到有任务的时候直接使用,这样我就不会频繁的创建和销毁线程了。这样大大提升了效率。

    在.NET中,很早就提倡任何需要线程的时刻都使用 ThreadPool。

    ps:现在觉大多数(我还没见过)的语言(runtime)中,线程与操作系统的线程是一一对应的。

    回归协程

    协程与线程是多对一的关系,有多个协程会对应到一根线程上。跟线程和CPU是一样的关系。

    线程是为了共享CPU,而协程是为了共享线程。

    协程是应用层面的自有"线程"实现。也就是说在不改变OS的线程逻辑下,自己构建了一套 "线程"系统。

    为什么不直接改动OS的线程,让其更轻?我个人觉得 1是历史兼容性问题,2是必要性问题,线程是一个很好的抽象逻辑。实现协程完全可以通过线程来完成。

    协程的目的

    我们来思考一个场景

    抓取百度、google、bing的html。

    多线程的做法是

    启动三个线程,分别对百度、google、bing发起HTTP GET请求。这时候使用了三个线程。

    协程的做法是(极端)

    启动一个线程对百度发起HTTP GET请求,将任务放入队列,在对google发起HTTP GET请求,将任务放入队列,在对bingHTTP GET请求将任务放入队列。

    这时候只需要使用一个线程(极端情况下,其实大多数实现来说至少需要两个线程,因为需要有一个后台线程去监听任务队列,当任务完成后再分配一个可用线程去处理下面的逻辑)

    为什么说极端情况下?因为协程有时候也可能会与线程一一对应,比如你的CPU有8个核心,同时跑4个协程也有可能会分配4根线程单独去处理这4个任务,这主要取决于调度算法。

    总结:协程是为了提升线程利用率,减少线程的无用功(大多数是IO堵塞),协程也更适合IO密集型的场景。

    C#中的协程

    可以看到,3个任务是异步执行的,但都由线程4来处理,也就是说三个异步任务只用了一根线程。

    C#中的CSP

    讲了这么大篇幅的协程,终于回归了今天的主题。

    其实单单实现CSP来说根本不用理清线程和协程。但今天主要对比的是Go中的CSP,所以如果没有协程基本是没有意义的。

    C#如何对应,CSP中最重要的Channel呢?

    答案就是:BlockingCollection

    我们来看一个例子

    抓取一批网站并输出网站的title

    发起 HTTP GET 请求 和分析Title的代码逻辑如下:

    主程序的代码如下:

    执行逻辑

    • 启用一个生产者协程来根据url生产对应的html、同时使用主线程消费队列内的内容(异步)

    • 每个url单独起一个协程来发起HTTP GET请求

    • 生产者协程等待所有url的html全部加载完成

    • 标志队列完成

    • 主线程退出

    执行结果如下:

    Go协程与.NET协程的区别?

    去除实现上的一些逻辑,本质上没太多区别。

    但Go有一个天生优势就是它是新时代的语言,抛弃了线程。也就是说Go层面没有线程的东西,它只有协程。

    但.NET中线程已经拥有了好多年,大量的类库、驱动使用线程来完成。

    所以你在上一层就算使用了协程,执行到底部不一定只有一根线程来完成,底部可以自己创建线程来运行逻辑,今天篇幅关系不做过多说明。后面我们在介绍这块的内容。

    到此,关于"C#怎么实现CSP并发模型"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

    线程 任务 语言 逻辑 C# 东西 队列 模型 内容 问题 处理 学习 调度 三个 上下 上下文 两个 也就是 也就是说 内存 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 咖啡豆 湖南永感互联网科技有限公司 江苏根荣互联网科技 厦门中拓互联网络科技有限公司 互联网下的科技发展 新浪科技互联网 撒么互联网科技公司 互联网公司会议桌创意科技软装饰 互联网科技公司需要的职位 科技与互联网的利与弊 宝灵互联网科技有限公司 互联网科技和法律行业 互联网在线教育科技创业 为客找房互联网科技公司怎么样 上海京穆互联网科技有限公司 美国互联网科技公司 互联网公司属于科技吗 科技互联网专业务虚会材料 科技互联网企业在行动 现代科技的标志之一的互联网 上海睿民互联网科技有限公司 互联网扶贫科技 没上市的科技互联网公司 壕鑫互联网络科技 团飞科技与伯堂互联网服务平台 重庆威客帮互联网科技 来此购互联网科技有限公司 互联网与数字科技关系 互联网科技收购价值 唐山双旺合互联网科技产业园
    0