日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
三分鐘掌握Actor和CSP模型

go的CSP模型

  • 傳統(tǒng)多線程的的共享內(nèi)存(ShareMemory)模型使用lock,condition等同步原語來強(qiáng)行規(guī)定進(jìn)程的執(zhí)行順序。
  • Actor模型,是基于消息傳遞的并發(fā)模型, 強(qiáng)調(diào)的是Actor這個(gè)工作實(shí)體,每個(gè)Actor自行決定消息傳遞的方向(要傳遞的ActorB),通過消息傳遞形成流水線。

本文現(xiàn)在要記錄的是另一種基于消息傳遞的并發(fā)模型:CSP(communicating sequential process順序通信過程)。

創(chuàng)新互聯(lián)建站自2013年起,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站建設(shè)、成都做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元利通做網(wǎng)站,已為上家服務(wù),為利通各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18982081108

在CSP模型,worker之間不直接彼此聯(lián)系,強(qiáng)調(diào)信道在消息傳遞中的作用,不謀求形成流水線。

消息的發(fā)送者和接受者通過該信道松耦合,發(fā)送者不知道自己消息被哪個(gè)接受者消費(fèi)了,接受者也不知道是從哪個(gè)發(fā)送者發(fā)送的消息。

go的信道

go的信道[1]是golang協(xié)程同步和通信的原生方式。

同map,slice一樣,channel通過make內(nèi)置函數(shù)初始化并返回引用,引用可認(rèn)為是常量指針[2]。

兩種信道:

1. 無緩沖區(qū)信道:讀寫兩端就緒后,才能通信(一方?jīng)]就緒就阻塞)。

這種方式可以用來在goroutine中進(jìn)行同步,而不必顯式鎖或者條件變量。

2. 有緩沖區(qū)信道:就有可能不阻塞, 只有buffer滿了,寫入才會(huì)阻塞;只有buffer空了,讀才會(huì)阻塞。

go的信道暫時(shí)先聊到這里。

我們來用以上背景做一道 有意思的面試題吧 。

兩個(gè)線程輪流打印0到100?

我不會(huì)啥算法,思路比較弱智:#兩線程#, #打印奇/偶數(shù)#, 我先復(fù)刻這兩個(gè)標(biāo)簽。

通過go的無緩沖信道的同步阻塞的能力對(duì)齊每一次循環(huán)。

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 { // 偶數(shù)
fmt.Println("g0 " + strconv.Itoa(i))
}
}
}()

go func() {
defer wg.Done()
for i := 0; i <= 100; i++ {
<-ch1
if i%2 == 1 { // 奇數(shù)
fmt.Println("g1 " + strconv.Itoa(i))
}
}
}()
wg.Wait()
}

題解:兩個(gè)協(xié)程都執(zhí)行0到100次循環(huán),但是不管哪個(gè)線程跑的快,在每次循環(huán)輸出時(shí)均會(huì)同步對(duì)齊, 每次循環(huán)時(shí)只輸出一個(gè)奇/偶值, 這樣也不用考慮兩個(gè)協(xié)程的啟動(dòng)順序。

思考我的老牌勁語C#要完成本題要怎么做?

依舊是#兩線程#、#打印奇偶數(shù)#, 我沒找到C#中能多次對(duì)齊線程的能力, 于是使用兩線程相互通知的方式。

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 + "== 偶數(shù)");
}
are2.Set();
}
});
Thread thread2 = new Thread(() =>
{
for (var i = 0; i <= 100; i++)
{
are2.WaitOne();
if (i % 2 == 1)
{
Console.WriteLine(i + "== 奇數(shù)");
}
are.Set();
}
});

thread1.Start();
thread2.Start();
Console.ReadKey();
}

注意:

  • volatile:提醒編譯器或運(yùn)行時(shí)系統(tǒng)不對(duì)字段做優(yōu)化(處于性能性能,編譯器/runtime會(huì)對(duì)同時(shí)執(zhí)行的線程訪問的同一字段進(jìn)行優(yōu)化,加volatile忽略這種優(yōu)化 )。
  • Object-->MarshalByRefObject-->WaitHandle-->EventWaitHandle--->AutoResetEvent[3] 本次使用了2個(gè)自動(dòng)重置事件來切換通知,由一個(gè)線程通知另外一個(gè)線程執(zhí)行。

引用鏈接

[1] go的信道: https://www.runoob.com/w3cnote/go-channel-intro.html

[2] 常量指針: https://zhuanlan.zhihu.com/p/133225100

[3] AutoResetEvent: https://docs.microsoft.com/en-us/dotnet/api/system.threading.autoresetevent?view=net-6.0


網(wǎng)頁題目:三分鐘掌握Actor和CSP模型
文章路徑:http://www.dlmjj.cn/article/djpjeds.html