三分钟掌控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,帮助我们解决了这个问题.这两个函数都能够 ...
随机推荐
- suse 12 二进制部署 Kubernetets 1.19.7 - 第04章 - 部署docker服务
文章目录 1.4.部署docker 1.4.0.下载docker二进制文件 1.4.1.配置docker镜像加速 1.4.2.配置docker为systemctl管理 1.4.3.启动docker服务 ...
- VS Code开发TypeScript
TypeScript是JaveScript的超集,为JavaScript增加了很多特性,它可以编译成纯JavaScript在浏览器上运行.TypeScript已经成为各种流行框架和前端应用开发的首选. ...
- 从Spring容器的角度理解Dubbo扩展点的加载时机
对于Dubbo提供的扩展点,主程序执行的过程中并没有显示调用加载的过程,无论是自激活的Filter还是自适应的ThreadPool.那么这样的扩展点在程序运行的哪个节点调用的呢?跟踪之前性能监控扩展点 ...
- 基于C#打造的OPCUA客户端应用
OPC UA (Unified Architecture),是工业4.0的标准通信规范,大家现在都不陌生. 目前大部分工控行业的应用系统都逐渐的在向OPC UA靠拢,所以随着iot的发展,OPC UA ...
- demo_2_27
#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>#include <string.h> int count_bit_one ...
- windows清理用户痕迹
1.日志管理器的基本使用 在这里创建自定义视图是非常重要的 在设置自定义视图不必设置的事件日志选项太多,可以按日志也可以按源进行设置,根据自己的情况来做决定 在cmd下可以使用wevtutil cl ...
- 案例五:shell脚本实现定时监控http服务的运行状态
注意:监控方法可以为端口.进程.URL模拟访问方式,或者三种方法综合. 说明:由于截止到目前仅讲了if语句,因此,就请大家用if语句来实现. [root@oldboy-B scripts]# cat ...
- C#委托Action、Action<T>、Func<T>、Predicate<T>系统自带的委托
C#委托Action.Action<T>.Func<T>.Predicate<T> CLR环境中给我们内置了几个常用委托Action. Action<T& ...
- Windows命令(ping、telnet、netstat详解)
转至:https://www.cnblogs.com/lisuyun/articles/5864744.html netstat详解转自http://wsmajunfeng.iteye.com/blo ...
- 5.注入内部Bean
我们将定义在 <bean> 元素的 <property> 或 <constructor-arg> 元素内部的 Bean,称为"内部 Bean". ...