三分钟掌控Actor模型和CSP模型
回顾一下前文《三分钟掌握共享内存模型和 Actor模型》
Actor vs CSP模型
- 传统多线程的的共享内存(ShareMemory)模型使用lock,condition等同步原语来强行规定进程的执行顺序。
- Actor模型,是基于消息传递的并发模型,强调的是Actor这个工作实体,每个Actor自行决定消息传递的方向(要传递的ActorB),通过消息传递形成流水线。
本文现在要记录的是另一种基于消息传递的并发模型: CSP(communicating sequential process顺序通信过程)。
在CSP模型,worker之间不直接彼此联系,强调信道在消息传递中的作用,不谋求形成流水线。
消息的发送者和接受者通过该信道松耦合,发送者不知道自己消息被哪个接受者消费了,接受者也不知道是从哪个发送者发送的消息。
go的信道
go的信道是golang协程同步和通信的原生方式。
同map,slice一样,channel通过make内置函数初始化并返回引用,引用可认为是常量指针。
两种信道:
- 无缓冲区信道:读写两端就绪后,才能通信(一方没就绪就阻塞)
这种方式可以用来在goroutine中进行同步,而不必显式锁或者条件变量。
- 有缓冲区信道:就有可能不阻塞, 只有buffer满了,写入才会阻塞;只有buffer空了,读才会阻塞。
go的信道暂时先聊到这里。
我们来用以上背景做一道 有意思的面试题吧 。
两个线程轮流打印0到100?
我不会啥算法,思路比较弱智:#两线程#, #打印奇/偶数#, 我先复刻这两个标签。
通过go的无缓冲信道的同步阻塞的能力对齐每一次循环。
package main
import (
"fmt"
"strconv"
"sync"
)
var wg sync.WaitGroup
var ch1 = make(chan struct{})
func main() {
wg.Add(2)
go func() {
defer wg.Done()
for i := 0; i <= 100; i++ {
ch1 <- struct{}{}
if i%2 == 0 { // 偶数
fmt.Println("g0 " + strconv.Itoa(i))
}
}
}()
go func() {
defer wg.Done()
for i := 0; i <= 100; i++ {
<-ch1
if i%2 == 1 { // 奇数
fmt.Println("g1 " + strconv.Itoa(i))
}
}
}()
wg.Wait()
}
题解: 两个协程都执行0到100次循环,但是不管哪个线程跑的快,在每次循环输出时均会同步对齐, 每次循环时只输出一个奇/偶值, 这样也不用考虑两个协程的启动顺序。
我们来思考我的老牌劲语C#要完成本题要怎么做?
依旧是#两线程#、#打印奇偶数#。
volatile static int i = 0;
static AutoResetEvent are = new AutoResetEvent(true);
static AutoResetEvent are2 = new AutoResetEvent(false);
public static void Main(String[] args)
{
Thread thread1 = new Thread(() =>
{
for (var i=0;i<=100;i++)
{
are.WaitOne();
if (i % 2 == 0)
{
Console.WriteLine(i + "== 偶数");
}
are2.Set();
}
});
Thread thread2 = new Thread(() =>
{
for (var i = 0; i <= 100; i++)
{
are2.WaitOne();
if (i % 2 == 1)
{
Console.WriteLine(i + "== 奇数");
}
are.Set();
}
});
thread1.Start();
thread2.Start();
Console.ReadKey();
}
注意两个:
- volatile:提醒编译器或运行时不对字段做优化(处于性能,编译器/runtime会对同时执行的线程访问的同一字段进行优化,加volatile忽略这种优化 )。
- Object-->MarshalByRefObject-->WaitHandle-->EventWaitHandle--->AutoResetEvent
本次使用了2个自动重置事件来切换通知,由一个线程通知另外一个线程执行。
三分钟掌控Actor模型和CSP模型的更多相关文章
- Actor模型和CSP模型的区别
引用至:http://www.jdon.com/concurrent/actor-csp.html Akka/Erlang的actor模型与Go语言的协程Goroutine与通道Channel代表的C ...
- 并发编程:Actors 模型和 CSP 模型
https://mp.weixin.qq.com/s/emB99CtEVXS4p6tRjJ2xww 并发编程:Actors 模型和 CSP 模型 ImportNew 2017-04-27
- 文本信息检索——布尔模型和TF-IDF模型
文本信息检索--布尔模型和TF-IDF模型 1. 布尔模型 如要检索"布尔检索"或"概率检索"但不包括"向量检索"方面的文档,其相应的查 ...
- 复杂领域的Cynefin模型和Stacey模型
最近好奇“复杂系统”,收集了点资料,本文关于Cynefin模型和Stacey模型.图文转自互联网后稍做修改. Cynefin模型提供一个从因果关系复杂情度来分析当前情况而作决定的框架,提出有五个领域: ...
- 贫血模型和DDD模型
贫血模型和DDD模型 1.贫血模型 1.1 概念 常见的mvc三层架构 简单.没有行为 2.领域驱动设计 2.1 概念(2004年提出的) Domain Driven Design 简称 DDD DD ...
- Inception模型和Residual模型卷积操作的keras实现
Inception模型和Residual残差模型是卷积神经网络中对卷积升级的两个操作. 一. Inception模型(by google) 这个模型的trick是将大卷积核变成小卷积核,将多个卷积核 ...
- 比较一下Linux下的Epoll模型和select模型的区别
一. select 模型(apache的常用) 1. 最大并发数限制,因为一个进程所打开的 FD (文件描述符)是有限制的,由 FD_SETSIZE 设置,默认值是 1024/2048 ,因此 Sel ...
- 利用生产者消费者模型和MQ模型写一个自己的日志系统-并发设计里一定会用到的手段
一:前言 写这个程序主要是用来理解生产者消费者模型,以及通过这个Demo来理解Redis的单线程取原子任务是怎么实现的和巩固一下并发相关的知识:这个虽然是个Demo,但是只要稍加改下Appender部 ...
- 网络编程中select模型和poll模型学习(linux)
一.概述 并发的网络编程中不管是阻塞式IO还是非阻塞式IO,都不能很好的解决同时处理多个socket的问题.操作系统提供了复用IO模型:select和poll,帮助我们解决了这个问题.这两个函数都能够 ...
随机推荐
- 【lwip】lwip源码基础
目录 前言 概念&作用 网络接口 概念引入 总结 lwip netif 结构体 链接 字段分析 网卡链表 网络 IP 接收数据函数 发送数据函数 ARP 模块调用的发送函数 出口回调函数 用户 ...
- zabbix-agentd;客户端开启多个端口。
学习标杆:https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/8/html/configuring_basic ...
- Redis 源码简洁剖析 16 - 客户端
整体概述 客户端属性 套接字描述符 标志 输入缓冲区 命名及命令参数 命令的实现函数 输出缓冲区 客户端的创建与关闭 创建普通客户端 关闭普通客户端 参考链接 Redis 源码简洁剖析系列 整体概述 ...
- Spring 类名后缀理解
Aware 理解 实现Spring的Aware接口. 定义为感知.意识,核心意义在于通过Aware可以把spring底层组件注入到自定义的bean中. 对于bean与容器的关系,bean不应该知道自身 ...
- python-利用random模块生成测试数据封装方法总结
1.前言: 在测试中经常有需要用到参数化,我们可以用random模块,faker模块生成测试数据,也可以用到pymysql,此文主要针对random模块生成任意个数的随机整数,随机字符串,随机手机号, ...
- 【基础篇】js对本地文件增删改查--改
前置条件: 1. 本地有安装node,点击传送门 项目目录: 1. msg.json内容 { "data": [ { "id": 1, "name&q ...
- 让你的Linux像黑客帝国的画面一样炫酷
#sudo apt-add-repository ppa:hollywood/ppa #sudo apt-get install hollywood #sudo apt-get install ...
- HDFS的上传下载流程
hdfs上传流程 首先客户端向nn请求上传文件.nn经过检查回应客户端是否可以上传.客户端得到同意后向nn请求上传第一块文件的dn.nn返回给客户端dn的地址.客户端与其中一个dn1建立连接然后dn1 ...
- Ng ML笔记
目录 一.线性回归 1,假设函数.代价函数,梯度下降 2,特征处理 3,代价函数和学习速率 4,特征和多项式回归 5,正规方程 二.逻辑回归(Logistic Regression,LR) 1,假设函 ...
- ElementUI Tree树形控件renderContent return时报错
问题描述: 使用Tree树形控件使用render-content渲染时return后报错或npm run dev时候报错,报错信息相同,如下: 问题分析: renderContent函数中需要使用js ...