为什么并发的 Golang 编程中会出现不同的数组长度输出?

huangapple go评论75阅读模式
英文:

Why different array length output in concurrent golang programming?

问题

我正在使用golang编写一个简单的并发测试程序,并且不理解每次运行时capitalized数组大小的不同输出!

data := []rune{'a', 'b', 'c', 'd'}
var capitalized []rune

capIt := func(r rune) {
    capitalized = append(capitalized, unicode.ToUpper(r))
    fmt.Printf("%c done!\n", r)
}

fmt.Printf("Before: %c\n", capitalized)
for i := 0; i < len(data); i++ {
    go capIt(data[i])
}
time.Sleep(100 * time.Millisecond)
fmt.Printf("After: %c\n", capitalized)

输出结果:

b done! a done! d done! c done! After: [D B C A]

a done! d done! c done! b done! After: [D B A]

d done! a done! c done! b done! After: [B]

d done! a done! c done! b done! After: [A B C]

d done! b done! a done! c done! After: [B C]

英文:

I'm writing a simple program in golang for concurrency test and don't understand different output of capitalized array size every time!

data := []rune{&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;}
var capitalized []rune

capIt := func(r rune) {
	capitalized = append(capitalized, unicode.ToUpper(r))
	fmt.Printf(&quot;%c done!\n&quot;, r)
}

fmt.Printf(&quot;Before: %c\n&quot;, capitalized)
for i := 0; i &lt; len(data); i++ {
	go capIt(data[i])
}
time.Sleep(100 * time.Millisecond)
fmt.Printf(&quot;After: %c\n&quot;, capitalized)

Outputs:

> b done! a done! d done! c done! After: [D B C A]

> a done! d done! c done! b done! After: [D B A]

> d done! a done! c done! b done! After: [B]

> d done! a done! c done! b done! After: [A B C]

> d done! b done! a done! c done! After: [B C]

答案1

得分: 2

Go: 数据竞争检测器


你有数据竞争。

$ go run -race racer.go
Before: []
=================
警告:数据竞争
由 goroutine 8 写入 0x00c000012018:
  main.main.func1()
      racer.go:14 +0xc4
  main.main.func2()
      racer.go:20 +0x3e

由 goroutine 7 之前读取 0x00c000012018:
  main.main.func1()
      racer.go:14 +0x44
  main.main.func2()
      racer.go:20 +0x3e

Goroutine 8(正在运行)创建于:
  main.main()
      racer.go:20 +0x199

Goroutine 7(正在运行)创建于:
  main.main()
      racer.go:20 +0x199
=================
a 完成!
=================
警告:数据竞争
由 goroutine 9 写入 0x00c000012018:
  main.main.func1()
      racer.go:14 +0xc4
  main.main.func2()
      racer.go:20 +0x3e

由 goroutine 10 之前写入 0x00c000012018:
  main.main.func1()
      racer.go:14 +0xc4
  main.main.func2()
      racer.go:20 +0x3e

Goroutine 9(正在运行)创建于:
  main.main()
      racer.go:20 +0x199

Goroutine 10(正在运行)创建于:
  main.main()
      racer.go:20 +0x199
=================
d 完成!
b 完成!
c 完成!
After: [B C]
发现 2 个数据竞争
退出状态 66
$ 

racer.go:

package main

import (
	"fmt"
	"time"
	"unicode"
)

func main() {
	data := []rune{'a', 'b', 'c', 'd'}
	var capitalized []rune

	capIt := func(r rune) {
		capitalized = append(capitalized, unicode.ToUpper(r))
		fmt.Printf("%c 完成!\n", r)
	}

	fmt.Printf("Before: %c\n", capitalized)
	for i := 0; i < len(data); i++ {
		go capIt(data[i])
	}
	time.Sleep(100 * time.Millisecond)
	fmt.Printf("After: %c\n", capitalized)
}
英文:

Go: Data Race Detector


You have data races.

$ go run -race racer.go
Before: []
==================
WARNING: DATA RACE
Write at 0x00c000012018 by goroutine 8:
  main.main.func1()
      racer.go:14 +0xc4
  main.main.func2()
      racer.go:20 +0x3e

Previous read at 0x00c000012018 by goroutine 7:
  main.main.func1()
      racer.go:14 +0x44
  main.main.func2()
      racer.go:20 +0x3e

Goroutine 8 (running) created at:
  main.main()
      racer.go:20 +0x199

Goroutine 7 (running) created at:
  main.main()
      racer.go:20 +0x199
==================
a done!
==================
WARNING: DATA RACE
Write at 0x00c000012018 by goroutine 9:
  main.main.func1()
      racer.go:14 +0xc4
  main.main.func2()
      racer.go:20 +0x3e

Previous write at 0x00c000012018 by goroutine 10:
  main.main.func1()
      racer.go:14 +0xc4
  main.main.func2()
      racer.go:20 +0x3e

Goroutine 9 (running) created at:
  main.main()
      racer.go:20 +0x199

Goroutine 10 (running) created at:
  main.main()
      racer.go:20 +0x199
==================
d done!
b done!
c done!
After: [B C]
Found 2 data race(s)
exit status 66
$ 

racer.go:

package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
	&quot;unicode&quot;
)

func main() {
	data := []rune{&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;}
	var capitalized []rune

	capIt := func(r rune) {
		capitalized = append(capitalized, unicode.ToUpper(r))
		fmt.Printf(&quot;%c done!\n&quot;, r)
	}

	fmt.Printf(&quot;Before: %c\n&quot;, capitalized)
	for i := 0; i &lt; len(data); i++ {
		go capIt(data[i])
	}
	time.Sleep(100 * time.Millisecond)
	fmt.Printf(&quot;After: %c\n&quot;, capitalized)
}

huangapple
  • 本文由 发表于 2023年6月25日 15:20:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76549313.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定