Wie sehen die verschiedenen Parallelitätsmodi in
golang aus? Der folgende Artikel wird Ihnen anhand von 20 animierten Bildern die Parallelität von Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] demonstrieren. Ich hoffe, dass er für alle hilfreich ist.
Wenn Sie diesen Artikel lieber per Video verstehen möchten, klicken Sie bitte, um meine Rede auf der Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]pherCon anzusehen www.youtube.com/watch?v=KyuFeiG3Y6...
Die leistungsstärksten Funktionen der Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]-Sprache Eine davon ist die integrierte Parallelität, die auf dem CSP-Papier von „Tony Hoare“ basiert. Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] wurde unter Berücksichtigung der Parallelität entwickelt und ermöglicht uns den Aufbau komplexer Parallelitätspipelines. Haben Sie sich jemals gefragt, wie die verschiedenen Parallelitätsmodi aussehen? Du musst darüber nachgedacht haben. Meistens denken wir über Probleme durch unsere Vorstellungskraft nach. Wenn ich Ihnen eine Frage zum Thema „Zahlen von 1 bis 100“ stelle, erscheinen unbewusst eine Reihe von Bildern in Ihrem Kopf. Ich stelle es mir zum Beispiel als eine gerade Linie vor, die bei mir beginnt, von den Zahlen 1 bis 20 verläuft und sich dann um 90 Grad nach rechts dreht, bis hin zu 1000+. Ich erinnere mich, als ich noch ganz klein war, in unserem Kindergarten, standen in der Garderobe viele Zahlen an der Wand und die Zahl 20 stand zufällig um die Ecke. Sie haben wahrscheinlich Ihr eigenes Bild von Zahlen. Ein weiteres häufiges Beispiel ist die visuelle Darstellung der Jahreszeiten – manche stellen sie sich als Kasten vor, andere als Kreis.
Wie auch immer, ich möchte Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] und WebGL verwenden, um Ihnen meine konkreten Versuche mit gemeinsamen Parallelitätsmustern zu zeigen. Dies spiegelt mehr oder weniger mein Verständnis von gleichzeitigen Programmen wider. Es wäre wirklich interessant zu hören, wie ich mich von dem Bild unterscheide, das Sie in Ihrem Kopf haben. Ich würde besonders gerne wissen, wie Rob Pike oder Sameer Ajmani sich die Parallelität vorstellen. Ich wette, es würde mich interessieren. [Verwandte Empfehlung:
Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]-Video-Tutorial]Lassen Sie uns unser heutiges Thema also mit einem sehr einfachen Beispiel „Hallo, gleichzeitige Welt“ beginnen.
package main func main() { // 创建一个int类型的通道 ch := make(chan int) // 开启一个匿名 goroutine go func() { // 向通道发送数字42 ch <p></p>Gehe zur interaktiven WebGL-Animation<p><a href="https://divan.dev/demos/hello/" target="_blank"></a>Die blaue Linie stellt die über die Zeit laufende Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]routine dar. Die dünne blaue Linie, die „main“ und „go #19“ verbindet, wird verwendet, um den Anfang und das Ende der Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]routine zu markieren Die Eltern-Kind-Beziehung wird angezeigt, und schließlich stellt die rote Linie die Sende-/Empfangsaktion dar. Obwohl es sich um zwei unabhängige Aktionen handelt, habe ich versucht, sie mit der Animation „von A nach B senden“ darzustellen. „#19“ im Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]routine-Namen ist die tatsächliche interne ID von Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]routine. Informationen zur Methode zum Abrufen finden Sie im Artikel „Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]routine-IDs“ von Scott Mansfield. <img src="https://img.php.cn/upload/article/000/000/024/03104ecc960e1992d7b04ec4cd79a77f-0.gif" alt="Hello, World"></p><p></p><h3> <span class="header-link octicon octicon-link">Timer</span><strong><span style="font-size: 18px;"></span>Tatsächlich können Sie einen einfachen Timer mit der folgenden Methode erstellen: Erstellen Sie einen Kanal, starten Sie eine Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]routine und lassen Sie sie nach einem bestimmten Zeitintervall Daten in den Kanal schreiben und geben Sie diese dann zurück Kanal zum Anrufer. Die aufrufende Funktion blockiert also das Auslesen des Kanals, bis das zuvor eingestellte Zeitintervall abgelaufen ist. Als nächstes rufen wir den Timer 24 Mal auf und versuchen, den Aufrufvorgang zu visualisieren. </strong><pre class="brush:php;toolbar:false">package main import "time" func timer(d time.Duration)
Zu interaktiven WebGL-Animationen gehen
package main import "time" func main() { var Ball int table := make(chan int) go player(table) go player(table) table <p>Zur interaktiven WebGL-Animation gehen</p> <p><a href="https://divan.dev/demos/pingpong/" target="_blank" textvalue="转到交互式 WebGL 动画"></a>Hier empfehle ich Ihnen, auf den <img src="https://img.php.cn/upload/article/000/000/024/6e2b2d910982ba58209c1c53cd9c7f6d-2.gif" alt="Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]">Link</p> zu klicken, um die interaktive WebGL-Animation zu verlangsamen oder zu beschleunigen und sie aus verschiedenen Blickwinkeln zu betrachten. <p><a href="https://divan.dev/demos/pingpong/" target="_blank">Jetzt fügen wir drei Spieler hinzu und werfen einen Blick darauf. </a></p><pre class="brush:php;toolbar:false"> go player(table) go player(table) go player(table)
转到交互式 WebGL 动画 我们可以看到每个玩家都按照次序轮流操作,你可能会想为什么会这样。为什么多个玩家(goroutine)会按照严格的顺序接到“球”呢。
答案是 Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] 运行时环境维护了一个 接收者 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="Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] 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">Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] 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> 的名称。在Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]中,此模式易于实现-只需以通道为参数启动多个goroutine,然后将值发送至该通道-Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]运行时会自动地进行分配和复用 :)</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="Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]"></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">Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] 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) } }
这不是很有趣-似乎并发方面没有发生任何事情。当然,在引擎盖下有很多复杂性,这是我们特意隐藏的。 “简单性很复杂”.
但是,让我们回到并发性并向我们的服务器添加一些交互。假设每个处理程序都希望异步写入记录器。在我们的示例中,记录器本身是一个单独的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">Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] to 交互式WebGL动画</a> <img src="https://img.php.cn/upload/article/000/000/024/dfdd69afd5511ae20942d0af033a1db2-9.gif" alt="Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] 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">Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] 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">Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] 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 'i' to channel 'ch'. } } //将值从通道“ in”复制到通道“ out”, //删除可被“素数”整除的那些。 func Filter(in <-chan int, out chan<- int, prime int) { for { i := <-in // Receive value from 'in'. if i%prime != 0 { out <- i // Send 'i' to 'out'. } } } //主筛:菊花链过滤器过程。 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 } }
,请以交互模式随意播放此动画。我喜欢它的说明性-它确实可以帮助您更好地理解该算法。 * generate * goroutine发出从2开始的每个整数,每个新的goroutine仅过滤特定的质数倍数-2、3、5、7 …,将第一个找到的质数发送给* main *。如果旋转它从顶部看,您会看到从goroutine发送到main的所有数字都是质数。漂亮的算法,尤其是在3D中。
现在,让我们回到我们的工作人员示例。还记得我告诉过它以GOMAXPROCS = 4运行吗?那是因为所有这些动画都不是艺术品,它们是真实程序的真实痕迹。
让我们回顾一下GOMAXPROCS是什么。
GOMAXPROCS设置可以同时执行的最大CPU数量。
当然,CPU是指逻辑CPU。我修改了一些示例,以使他们真正地工作(而不仅仅是睡觉)并使用实际的CPU时间。然后,我运行了代码,没有进行任何修改,只是设置了不同的GOMAXPROCS值。 Linux机顶盒有2个CPU,每个CPU具有12个内核,因此有24个内核。
因此,第一次运行演示了该程序在1个内核上运行,而第二次-使用了所有24个内核的功能。
WebGL动画-1| WebGL动画-24GOMAXPROCS1
Die Zeitgeschwindigkeit in diesen Animationen ist unterschiedlich (ich möchte, dass alle Animationen zur gleichen Zeit/Höhe passen), daher ist der Unterschied spürbar. Wenn GOMAXPROCS = 1, kann der nächste Arbeiter erst mit der eigentlichen Arbeit beginnen, nachdem der vorherige abgeschlossen ist. Im Fall von GOMAXPROCS = 24 ist die Beschleunigung sehr groß, während der Multiplex-Overhead vernachlässigbar ist.
Es ist jedoch wichtig zu verstehen, dass eine Erhöhung von GOMAXPROCS nicht immer zu einer Leistungsverbesserung führt, sondern in manchen Fällen sogar zu einer Verschlechterung führen kann.
Was können wir anhand der Parallelitätszeiten in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] beweisen? Eine Sache, die mir in den Sinn kommt, sind Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]routine-Lecks. Wenn Sie beispielsweise eine Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]routine starten, diese jedoch den Gültigkeitsbereich verlässt , kann ein Leck auftreten. Oder Sie haben einfach vergessen, die Endbedingung hinzuzufügen und stattdessen eine for{}-Schleife ausgeführt.
Als ich zum ersten Mal auf ein Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]routine-Leck in meinem Code stieß, kamen mir gruselige Bilder in den Sinn, und am nächsten Wochenende schrieb ich expvarmon. Jetzt kann ich dieses gruselige Bild mit WebGL visualisieren.
Sehen Sie sich Folgendes an:
Es tut mir schon weh, das zu sehen :) Alle diese Zeilen verschwenden Ressourcen und sind eine tickende Zeitbombe für Ihr Programm.
Das Letzte, was ich veranschaulichen möchte, ist der Unterschied zwischen Parallelität und Parallelität. Dieses Thema deckt viel ab und Rob Pike hat einen wundervollen Vortrag zu diesem Thema gehalten. Wirklich eines der #must-watch-Videos.
Kurz gesagt:
Parallel bedeutet einfach, dass Dinge parallel laufen.
Parallelität ist eine Möglichkeit, Programme zu strukturieren.
Daher können gleichzeitige Programme parallel sein oder auch nicht, und diese Konzepte sind in gewisser Weise orthogonal. Das haben wir bereits gesehen, als wir die Wirkung der GOMAXPROCS-Einstellung demonstriert haben.
Ich könnte all diese verlinkten Artikel und Vorträge wiederholen, aber ein Bild sagt mehr als tausend Worte. Was ich hier tun kann, ist, den Unterschied zu visualisieren. Es ist also parallel. Viele Dinge laufen parallel.
Gehe zu Interaktiver WebGL-Animation
Dies ist auch parallel:
Gehe zu Interaktiver WebGL-Animation
Aber das ist gleichzeitig:
Und das:
Das ist auch gleichzeitig:
Um diese Animationen zu erstellen, habe ich zwei Programme geschrieben: gotracer und die go three.js-Bibliothek. Zunächst führt gotracer Folgendes aus:
Generiertes JSON-Beispiel:
Als nächstes nutzt go three.js die Leistungsfähigkeit der erstaunlichen Three.js-Bibliothek, um 3D-Linien und -Objekte mithilfe von WebGL zu zeichnen. Ich habe ein paar ganz kleine Umbrüche gemacht, damit es in eine einzelne HTML-Seite passt – das war's.
Diese Methode ist jedoch sehr begrenzt. Ich musste meine Beispiele genau auswählen, Kanäle und Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]routinen umbenennen, damit der mehr oder weniger komplexe Code korrekte Spuren erzeugt. Bei diesem Ansatz gibt es keine einfache Möglichkeit, Kanäle zwischen Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]routinen zu verknüpfen, wenn sie unterschiedliche Namen haben. Ganz zu schweigen von den Kanälen, die über Kanäle vom Typ „Chan“ gesendet werden. Es gibt auch große Probleme mit dem Timing – die Ausgabe an stdout kann mehr Zeit in Anspruch nehmen als das Senden des Werts, daher muss ich in manchen Fällen einen Time.Sleep (einige Millisekunden) einstellen, um die Animation richtig hinzubekommen.
Grundsätzlich habe ich deshalb noch keinen Open-Source-Code. Ich spiele mit dem Execution Tracker von Dmitry Vyukov herum, der zwar Details zum Ereignis zu liefern scheint, aber nicht die Übermittlung wertvoller Informationen beinhaltet. Vielleicht gibt es einen besseren Weg, das gewünschte Ziel zu erreichen. Wenn Sie Ideen haben, schreiben Sie mir eine Nachricht auf Twitter oder in den Kommentaren. Es wäre großartig, wenn dieses zweiwöchige Tool zu einem echten Debugging-/Tracing-Tool für jedes Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen]-Programm erweitert werden könnte.
Ich würde auch gerne weitere interessante Parallelitätsalgorithmen und -muster sehen, die hier nicht aufgeführt sind. Schreibt es uns gerne in die Kommentare.
Viel Spaß beim Codieren!
UPD: Dieses Tool ist unter github.com/pan/gotrace verfügbar und generiert Traces mit Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] Execution Tracer und einer gepatchten Laufzeit.
Außerdem bin ich offen für neue Jobs. Wenn Ihr Unternehmen/Team also an mir interessiert ist und ein schwieriges Problem mit Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Ausführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] in einem Artikel [20 animierte Bilddemonstrationen] zu lösen hat, kann ich remote arbeiten (oder Sie sind in Barcelona) und stellen Sie ein. Bitte lassen Sie zu Ich weiß :)
Englische Originaladresse: https://divan.dev/posts/go_concurrency_visualize/
Weitere Programmierkenntnisse finden Sie unter: Programmiervideo! !
Das obige ist der detaillierte Inhalt vonAusführliche Erklärung der Parallelität in Go in einem Artikel [20 animierte Bilddemonstrationen]. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!