ホームページ  >  記事  >  バックエンド開発  >  Goの並行性を詳しく解説【アニメーション20枚】

Goの並行性を詳しく解説【アニメーション20枚】

青灯夜游
青灯夜游転載
2022-09-08 10:48:261764ブラウズ

golang のさまざまな同時実行モードはどのようなものですか?次の記事では、20 枚のアニメーション画像を通して Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 の同時実行について説明します。

Goの並行性を詳しく解説【アニメーション20枚】

#この記事についてビデオで学びたい場合は、クリックして Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】pherCon www.youtube.com で私の講演をご覧ください。 /watch? v=KyuFeiG3Y6...

Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 言語の最も強力な機能の 1 つは、Tony Hoare の CSP この論文に基づいて実装された組み込み同時実行機能です。は同時実行を念頭に置いて設計されており、複雑な同時実行パイプラインを構築できます。さまざまな同時実行モードがどのようなものであるか考えたことはありますか?

きっと考えたことがあるはずです。私たちは想像力で問題を考えることがほとんどですが、「1から100までの数字」について質問すると、無意識のうちに一連の絵が頭の中に浮かび上がります。たとえば、私から出発して数字の 1 から 20 まで進み、その後右に 90 度曲がって 1000 まで続く直線として想像します。私が幼い頃、幼稚園のクロークの壁にたくさんの数字が書かれていて、たまたま角を曲がったところに20という数字があったことを覚えています。おそらくあなたは数字について独自のイメージを持っているでしょう。もう 1 つの一般的な例は、一年の季節を視覚的に表現したものです。これを箱として想像する人もいれば、円として想像する人もいます。

いずれにせよ、Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 と WebGL を使用して、一般的な同時実行パターンに対する具体的な試みを示したいと思います。これは多かれ少なかれ、同時実行プログラムに関する私の理解を表しています。あなたの頭の中にあるイメージと私がどのように違うのかを聞くのは本当に興味深いでしょう。特に、Rob Pike 氏や Sameer Ajmani 氏が頭の中で同時実行性をどのように描いているのか知りたいと思っています。 [関連する推奨事項: Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 ビデオ チュートリアル ]

それでは、今日のトピックを非常に基本的な「Hello, Concurrent World」の例から始めましょう。

こんにちは、コンカレントワールド

コードは非常に単純です - 単一のチャネル、単一の goroutine、単一の書き込み、単一読む。

package main

func main() {
    // 创建一个int类型的通道
    ch := make(chan int)

    // 开启一个匿名 goroutine
    go func() {
        // 向通道发送数字42
        ch <p><a href="https://divan.dev/demos/hello/" target="_blank">インタラクティブな WebGL アニメーションに移動</a> <img src="https://img.php.cn/upload/article/000/000/024/03104ecc960e1992d7b04ec4cd79a77f-0.gif" alt="Hello, World"></p><p>青い線は、時間の経過とともに実行されるゴルーチンを表します。青い線は、「main」と「go #19」を接続します。細い色の線は、ゴルーチンの開始と終了をマークし、親子関係を示すために使用されます。最後の赤い線は、送信/受信アクションを表します。これらは 2 つの独立したアクションですが、「送信元」を使用してみました。ゴルーチン名の「#19」はゴルーチンの実際の内部IDです。取得方法については、Scott Mansfield氏の記事「Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】routine IDs」を参照してください。 </p><h3>
<span class="header-link octicon octicon-link"></span><strong><span style="font-size: 18px;">タイマー</span></strong>
</h3><p> 実際には、チャネルを作成し、Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】routine を開始してデータを書き込むことで、単純なタイマーを構築できます。指定された時間間隔の後にチャネルに送信し、チャネルを呼び出し元に返します。したがって、呼び出し側関数は、以前に設定された時間が経過するまで、チャネルの読み取り時にブロックされます。次にタイマーを 24 回呼び出し、呼び出しプロセスを視覚化してみます。 </p><pre class="brush:php;toolbar:false">package main

import "time"

func timer(d time.Duration) <p><a href="https://divan.dev/demos/timers/" target="_blank">インタラクティブ WebGL アニメーションに移動</a> <img src="https://img.php.cn/upload/article/000/000/024/6e2b2d910982ba58209c1c53cd9c7f6d-1.gif" alt="Recurrent Timers"></p><p> なかなかいいですね?先に進みましょう。 </p><h3>
<span class="header-link octicon octicon-link"></span><strong><span style="font-size: 18px;">ピンポン</span></strong>
</h3><p>この同時実行の例は、Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】ogle 従業員 Sameer Ajmani の「<a href="https://talks.golang.org/2013/advconc.slide#1" target="_blank" textvalue="Advanced Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 Concurrency Patterns">Advanced Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 Concurrency」から引用しています。パターン </a>」のスピーチ。もちろん、このパターンはそれほど高度なものではありませんが、Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 の同時実行メカニズムにしか精通していない人にとっては、新しくて興味深いものに見えるかもしれません。 </p><p>ここでは、卓球台を表すためにチャネルを使用します。整数変数はボールを表し、次に 2 つのゴルーチンを使用してプレーヤーを表します。プレーヤーは、整数変数の値を増やすことによってバッティング アクションをシミュレートします。 (カウンターをクリックします)。 </p><pre class="brush:php;toolbar:false">package main

import "time"

func main() {
    var Ball int
    table := make(chan int)
    go player(table)
    go player(table)

    table <p><a href="https://divan.dev/demos/pingpong/" target="_blank" textvalue="转到交互式 WebGL 动画">インタラクティブ WebGL アニメーションに移動</a> <img src="https://img.php.cn/upload/article/000/000/024/6e2b2d910982ba58209c1c53cd9c7f6d-2.gif" alt="Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】"></p><p>ここで、<a href="https://divan.dev/demos/pingpong/" target="_blank"> リンク </a> をクリックしてインタラクティブ WebGL アニメーションに入ることをお勧めします。アニメーションを低速または高速にして、さまざまな角度から表示します。 </p><p>それでは、3 人のプレイヤーを追加して見てみましょう。 </p><pre class="brush:php;toolbar:false">    go player(table)
    go player(table)
    go player(table)

转到交互式 WebGL 动画 Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 3 我们可以看到每个玩家都按照次序轮流操作,你可能会想为什么会这样。为什么多个玩家(goroutine)会按照严格的顺序接到“球”呢。

答案是 Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 运行时环境维护了一个 接收者 FIFO 队列 (存储需要从某一通道上接收数据的goroutine),在我们的例子里,每个玩家在刚发出球后就做好了接球准备。我们来看一下更复杂的情况,加入100个玩家。

for i := 0; i <p><a href="https://divan.dev/demos/pingpong100/" target="_blank">转到交互式 WebGL 动画</a> <img src="https://img.php.cn/upload/article/000/000/024/f022e6361217c7f4c90e16d8d0885f99-4.gif" alt="Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 100"> </p><p>先进先出顺序很明显了,是吧? 我们可以创建一百万个goroutine,因为它们很轻量,但是对于实现我们的目的来说没有必要。我们来想想其他可以玩的。 例如, 常见的消息传递模式。</p><h3>
<span class="header-link octicon octicon-link"></span><strong><span style="font-size: 18px;">Fan-In</span></strong>
</h3><p>并发世界中流行的模式之一是所谓的 <em>fan-in</em> 模式。这与 <em>fan-out</em> 模式相反,稍后我们将介绍。简而言之,fan-in 是一项功能,可以从多个输入中读取数据并将其全部多路复用到单个通道中。</p><p>举例来说:</p><pre class="brush:php;toolbar:false">package main

import (
    "fmt"
    "time"
)

func producer(ch chan int, d time.Duration) {
    var i int
    for {
        ch <p><a href="https://divan.dev/demos/fanin/" target="_blank">Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 to interactive WebGL animation</a> <img src="https://img.php.cn/upload/article/000/000/024/f022e6361217c7f4c90e16d8d0885f99-5.gif" alt="Fan-In Pattern"></p><p>如我们所见,第一个 <em>producer</em> 每100毫秒生成一次值,第二个每250毫秒生成一次值,但是 <em>reader</em> 会立即从这两个生产者那里接受值。实际上,多路复用发生在 <em>main</em> 的range循环中。</p><h3>
<span class="header-link octicon octicon-link"></span><strong><span style="font-size: 18px;">Workers</span></strong>
</h3><p>与 <em>fan-in</em> 相反的模式是 <em>fan-out</em> 或者<em>worker</em> 模式。多个 goroutine 可以从单个通道读取,从而在CPU内核之间分配大量的工作量,因此是 <em>worker</em> 的名称。在Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】中,此模式易于实现-只需以通道为参数启动多个goroutine,然后将值发送至该通道-Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】运行时会自动地进行分配和复用 :)</p><pre class="brush:php;toolbar:false">package main

import (
    "fmt"
    "sync"
    "time"
)

func worker(tasksCh <p><img src="https://img.php.cn/upload/article/000/000/024/bc82f8929dc05185db5d2b4542d2ca73-6.gif" alt="Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】"></p><p>这里值得一提的是:并行性。如您所见,所有goroutine并行’运行‘,等待通道给予它们’工作‘。鉴于上面的动画,很容易发现goroutine几乎立即接连地收到它们的工作。不幸的是,该动画在goroutine确实在处理工作还是仅仅是在等待输入的地方没有用颜色显示出来,但是此动画是在GOMAXPROCS=4的情况下录制的,因此只有4个goroutine有效地并行运行。我们将很快讨论这个主题。</p><p>现在,让我们做一些更复杂的事情,并启动一些有自己workers(subworkers)的workers。</p><pre class="brush:php;toolbar:false">package main

import (
    "fmt"
    "sync"
    "time"
)

const (
    WORKERS    = 5
    SUBWORKERS = 3
    TASKS      = 20
    SUBTASKS   = 10
)

func subworker(subtasks chan int) {
    for {
        task, ok := <p><a href="https://divan.dev/demos/workers2/" target="_blank">Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 to interactive WebGL animation</a> <img src="https://img.php.cn/upload/article/000/000/024/bc82f8929dc05185db5d2b4542d2ca73-7.gif" alt="Workers of workers"> 很好。当然,我们可以将worker和subworker的数量设置为更高的值,但是我试图使动画清晰易懂。</p><p>更酷的 fan-out 模式确实存在,例如动态数量的worker/subworker,通过通道发送通道,但是 fan-out 的想法现在应该很清楚了。</p><h3>
<span class="header-link octicon octicon-link"></span><strong><span style="font-size: 18px;">服务器</span></strong>
</h3><p>下一个常见的模式类似于扇出,但是会在很短的时间内生成goroutine,只是为了完成某些任务。它通常用于实现服务器-创建侦听器,循环运行accept()并为每个接受的连接启动goroutine。它非常具有表现力,可以实现尽可能简单的服务器处理程序。看一个简单的例子:</p><pre class="brush:php;toolbar:false">package main

import "net"

func handler(c net.Conn) {
    c.Write([]byte("ok"))
    c.Close()
}

func main() {
    l, err := net.Listen("tcp", ":5000")
    if err != nil {
        panic(err)
    }
    for {
        c, err := l.Accept()
        if err != nil {
            continue
        }
        go handler(c)
    }
}

Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 to 交互式WebGL动画 Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 

这不是很有趣-似乎并发方面没有发生任何事情。当然,在引擎盖下有很多复杂性,这是我们特意隐藏的。 “简单性很复杂”.

但是,让我们回到并发性并向我们的服务器添加一些交互。假设每个处理程序都希望异步写入记录器。在我们的示例中,记录器本身是一个单独的goroutine,它可以完成此任务。

package main

import (
    "fmt"
    "net"
    "time"
)

func handler(c net.Conn, ch chan string) {
    ch <p><a href="https://divan.dev/demos/servers2/" target="_blank">Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 to 交互式WebGL动画</a> <img src="https://img.php.cn/upload/article/000/000/024/dfdd69afd5511ae20942d0af033a1db2-9.gif" alt="Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 2"> </p><p>不是吗?但是很容易看到,如果请求数量增加并且日志记录操作花费一些时间(例如,准备和编码数据),我们的* logger * goroutine很快就会成为瓶颈。我们可以使用一个已知的扇出模式。我们开始做吧。</p><h3>
<span class="header-link octicon octicon-link"></span><strong><span style="font-size: 18px;">服务器+工作者</span></strong>
</h3><p>带工作程序的服务器示例是记录器的高级版本。它不仅可以完成一些工作,而且还可以通过* results *通道将其工作结果发送回池中。没什么大不了的,但是它将我们的记录器示例扩展到了更实际的示例。</p><p>让我们看一下代码和动画:</p><pre class="brush:php;toolbar:false">package main

import (
    "net"
    "time"
)

func handler(c net.Conn, ch chan string) {
    addr := c.RemoteAddr().String()
    ch <p><a href="https://divan.dev/demos/servers3/" target="_blank">Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 to 交互式WebGL动画</a> <img src="https://img.php.cn/upload/article/000/000/024/d04fb172e580bf3c4b0bca0edac0a234-10.gif" alt="Server + Worker"> 我们在4个goroutine之间分配了工作,有效地提高了记录器的吞吐量,但是从此动画中,我们可以看到记录器仍然可能是问题的根源。成千上万的连接在分配之前会汇聚在一个通道中,这可能导致记录器再次成为瓶颈。但是,当然,它会在更高的负载下发生。</p><h3>
<span class="header-link octicon octicon-link"></span><strong><span style="font-size: 18px;">并发素筛(素筛指素数筛法)</span></strong>
</h3><p>足够的扇入/扇出乐趣。让我们看看更复杂的并发算法。我最喜欢的例子之一是Concurrent Prime Sieve,可以在[<a href="https://talks.golang.org/2012/concurrency.slide" target="_blank">Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 Concurrency Patterns</a>]对话中找到。素数筛,或<a href="https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes" target="_blank">[Eratosthenes筛)</a>是一种古老的算法,用于查找达到给定限制的素数。它通过按顺序消除所有质数的倍数来工作。天真的算法并不是真正有效的算法,尤其是在多核计算机上。</p><p>该算法的并发变体使用goroutine过滤数字-每个发现的素数一个goroutine,以及用于将数字从生成器发送到过滤器的通道。找到质数后,它将通过通道发送到* main *以进行输出。当然,该算法也不是很有效,特别是如果您想找到大质数并寻找最低的Big O复杂度,但是我发现它非常优雅。</p><pre class="brush:php;toolbar:false">// 并发的主筛
package main

import "fmt"

// 将序列2、3、4,...发送到频道“ ch”。
func Generate(ch chan<- int) {
    for i := 2; ; i++ {
        ch <- i // Send &#39;i&#39; to channel &#39;ch&#39;.
    }
}

//将值从通道“ in”复制到通道“ out”,
//删除可被“素数”整除的那些。
func Filter(in <-chan int, out chan<- int, prime int) {
    for {
        i := <-in // Receive value from &#39;in&#39;.
        if i%prime != 0 {
            out <- i // Send &#39;i&#39; to &#39;out&#39;.
        }
    }
}

//主筛:菊花链过滤器过程。
func main() {
    ch := make(chan int) // Create a new channel.
    go Generate(ch)      // Launch Generate goroutine.
    for i := 0; i < 10; i++ {
        prime := <-ch
        fmt.Println(prime)
        ch1 := make(chan int)
        go Filter(ch, ch1, prime)
        ch = ch1
    }
}

转到交互式WebGL动画

Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】

,请以交互模式随意播放此动画。我喜欢它的说明性-它确实可以帮助您更好地理解该算法。 * generate * goroutine发出从2开始的每个整数,每个新的goroutine仅过滤特定的质数倍数-2、3、5、7 …,将第一个找到的质数发送给* main *。如果旋转它从顶部看,您会看到从goroutine发送到main的所有数字都是质数。漂亮的算法,尤其是在3D中。

GOMAXPROCS(调整并发的运行性能)

现在,让我们回到我们的工作人员示例。还记得我告诉过它以GOMAXPROCS = 4运行吗?那是因为所有这些动画都不是艺术品,它们是真实程序的真实痕迹。

让我们回顾一下GOMAXPROCS是什么。

GOMAXPROCS设置可以同时执行的最大CPU数量。

当然,CPU是指逻辑CPU。我修改了一些示例,以使他们真正地工作(而不仅仅是睡觉)并使用实际的CPU时间。然后,我运行了代码,没有进行任何修改,只是设置了不同的GOMAXPROCS值。 Linux机顶盒有2个CPU,每个CPU具有12个内核,因此有24个内核。

因此,第一次运行演示了该程序在1个内核上运行,而第二次-使用了所有24个内核的功能。

WebGL动画-1| WebGL动画-24GOMAXPROCS1

Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】

これらのアニメーションの時間の速度は異なるため (すべてのアニメーションを同じ時間/高さに合わせたい)、その違いは顕著です。 GOMAXPROCS = 1 の場合、次のワーカーは前のワーカーが完了した後にのみ実際の作業を開始できます。 GOMAXPROCS = 24 の場合、高速化は非常に大きくなりますが、多重化のオーバーヘッドは無視できます。

ただし、GOMAXPROCS を増やしても必ずしもパフォーマンスが向上するとは限らず、場合によっては実際にパフォーマンスが悪化する可能性があることを理解することが重要です。

Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】routines リーク

Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 の同時実行時間から何が証明できるでしょうか?思い当たることの 1 つは、Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】routine リークです。たとえば、ゴルーチンを 開始したがスコープ から外れると、リークが発生する可能性があります。あるいは、単に終了条件を追加するのを忘れて、代わりに for{} ループを実行しただけです。

コード内で goroutine リークに初めて遭遇したとき、恐ろしいイメージが頭に浮かび、次の週末にかけて expvarmon を書きました。 WebGL を使用して、この恐ろしい画像を視覚化できるようになりました。

見てください:

Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】

これを見るだけで心が痛みます:) これらの行はすべてリソースの無駄であり、プログラムの一部です 時限爆弾。

#並列処理は同時実行ではありません

最後に明確にしておきたいのは、並列処理と同時実行の違いです。 。このトピック

では たくさんの内容を取り上げており、ロブ パイクはこのトピックについて 素晴らしいスピーチ を行いました。本当に #必見のビデオ の 1 つです。 つまり、

並列処理とは、単純に物事を並行して実行することです。

同時実行とは、プログラムを構築する方法の 1 つです。

したがって、並行プログラムは並列である場合とそうでない場合があり、これらの概念はある程度直交しています。これは、GOMAXPROCS 設定の効果を実証したときにすでに確認されています。

リンクされた記事や講演をすべて繰り返すこともできますが、百聞は一見に如かずです。ここで私にできることは、違いを視覚化することです。だから平行なんです。多くのことが並行して実行されます。

インタラクティブ WebGL アニメーションに移動

并行 1これも並列処理です:

インタラクティブ WebGL アニメーションに移動

Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】ただし、これは同時です:

Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】そしてこれ:

Workers of workersこれも同時実行です:

Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】

##作り方 作成するにはこれらのアニメーションを作成するために、gotracer

ライブラリと

gothree.js ライブラリという 2 つのプログラムを作成しました。まず、gotracer は次の処理を実行します。 Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 プログラムの AST ツリー (抽象構文ツリー) を解析し、同時実行関連イベントの出力を含む特別なコマンドを挿入します - ゴルーチンの開始/停止、チャネルの作成、チャネルとの間で送受信します。

    生成されたプログラムを実行する
  • この特別な出力を分析し、イベントとタイムスタンプの説明を含む JSON を生成します。
  • 生成された JSON の例:

次に、gothree.js は、驚くべき JSON sampleThree.js

ライブラリの機能を使用して、WebGL 3D ラインを描画し、オブジェクト。単一の HTML ページに収まるように非常に小さなラッピングを行いました。それだけです。

ただし、この方法は非常に限られています。多かれ少なかれ複雑なコードで正しいトレースを生成するには、サンプルを正確に選択し、チャネルとゴルーチンの名前を変更する必要がありました。このアプローチでは、チャネルの名前が異なる場合、ゴルーチン間でチャネルを関連付ける簡単な方法はありません。 chan タイプのチャネルで送信されるチャネルは言うまでもありません。タイミングにも大きな問題があります。標準出力への出力は値の送信よりも時間がかかる可能性があるため、場合によっては、アニメーションを正しく表示するために time.Sleep (数ミリ秒) を設定する必要があります。

基本的に、これが私がまだオープンソース コードを持っていない理由です。私は Dmitry Vyukov の Execution Tracker を試しています。イベントの詳細は提供されるようですが、価値のある情報の送信は含まれていません。もしかしたら、目的の目標を達成するためのより良い方法があるかもしれません。アイデアがある場合は、twitter で私にラインをドロップするか、コメントにラインをドロップしてください。この 2 週間のツールを、あらゆる Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 プログラムの実際のデバッグ/トレース ツールに拡張できれば素晴らしいと思います。

ここにリストされていない、さらに興味深い同時実行アルゴリズムやパターンも見てみたいと思っています。コメントにお気軽に書き込んでください。

ハッピーコーディング!

UPD: このツールは github.com/pan/gotrace で入手でき、Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 Execution Tracer とパッチ適用されたランタイム トラックを使用して生成されます。

また、私は新しい仕事を受け入れる用意があります。そのため、あなたの会社/チームが私に興味を持っていて、Goの並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】の並行性を詳しく解説【アニメーション20枚】 を使用して解決するのが難しい問題を抱えている場合は、リモート (またはバルセロナにいる場合) で働くことができ、雇用しています。教えてください:)

英語の元のアドレス: https://divan.dev/posts/go_concurrency_visualize/

プログラミング関連の知識の詳細については、次を参照してください。 プログラミングビデオ ! !

以上がGoの並行性を詳しく解説【アニメーション20枚】の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlearnku.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。