如何在彩票中心下载中使用原子函数解决竞争条件?

争用条件是由于对共享资源的不同步访问而引起的,并试图同时读取和写入该资源。

原子函数提供了用于同步访问整数和指针的低级锁定机制。原子功能通常用于修复竞争条件。

中的功能 原子同步 软件包通过锁定对共享资源的访问来提供支持同步goroutine的支持。

package main

import (
	"fmt"
	"runtime"
	"同步"
	"同步/atomic"
)

var (
	counter int32          // counter is a variable incremented by all goroutines.
	wg      同步.WaitGroup // wg is used to wait for the program to finish.
)

func main() {
	wg.Add(3) // Add a count of two, one for each goroutine.

	go increment("Python")
	go increment("Java")
	go increment("高朗")

	wg.Wait() // Wait for the goroutines to finish.
	fmt.Println("Counter:", counter)

}

func increment(name string) {
	defer wg.Done() // Schedule the call to Done to tell main we are done.

	for range name {
		atomic.AddInt32(&counter,1)
		runtime.Gosched() // Yield the thread and be placed back in queue.
	}
}

AddInt32 通过强制每次只能执行一个goroutine并完成一次加法操作,atomic软件包中的function可以同步整数值的加法。当goroutine尝试调用任何原子函数时,它们会自动与所引用的变量同步。

运行上面的程序时,您可以看到以下输出:

C:\彩票中心下载\goroutines>go run -race main.go
Counter: 15

C:\彩票中心下载\goroutines>

请注意,如果您替换代码行 原子.AddInt32(&counter,1)计数器++,那么您将看到以下输出-

C:\彩票中心下载\goroutines>go run -race main.go
==================
WARNING: DATA RACE
Read at 0x0000006072b0 by goroutine 7:
  main.increment()
      C:/彩票中心下载/goroutines/main.go:31 +0x76

Previous write at 0x0000006072b0 by goroutine 8:
  main.increment()
      C:/彩票中心下载/goroutines/main.go:31 +0x90

Goroutine 7 (running) created at:
  main.main()
      C:/彩票中心下载/goroutines/main.go:18 +0x7e

Goroutine 8 (running) created at:
  main.main()
      C:/彩票中心下载/goroutines/main.go:19 +0x96
==================
Counter: 15
Found 1 data race(s)
exit status 66

C:\彩票中心下载\goroutines>

您必须阅读的解决方案

如何杀死goroutine的执行?

通道具有关闭通道的关闭操作,因此无法在通道上进行发送操作。在关闭的通道上进行发送操作将导致恐慌。 在通道上执行接收操作时,我们检查通道是否关闭,如果通道关闭,则从goroutine退出。

如何等待Goroutine完成执行?

同步包的WaitGroup类型,用于等待程序完成从主函数启动的所有goroutine。它使用一个指定goroutine数量的计数器,并且Wait阻止程序执行,直到WaitGroup计数器为零。 Add方法用于将计数器添加到WaitGroup。 使用defer语句调度WaitGroup的Done方法,以减少WaitGroup计数器。 WaitGroup类型的Wait方法等待程序完成所有goroutine。 在主函数内部调用Wait方法,该函数将阻止执行,直到WaitGroup计数器的值为零为止,并确保所有goroutine都已执行。

What is goroutines?

高朗中的并发是功能彼此独立运行的能力。 Goroutine是可以同时运行的函数。 高朗提供Goroutines作为并发处理操作的一种方式。 新的goroutines由go语句创建。 要将函数作为goroutine运行,请调用以go语句为前缀的函数。这是示例代码块: sum()//一个正常的函数调用,它会同步执行sum并等待其完成 go sum()//一个goroutine,它异步执行sum而不等待完成它 go关键字使函数调用立即返回,而该函数作为goroutine开始在后台运行,而程序的其余部分继续执行。每个彩票中心下载程序的主要功能都是使用goroutine启动的,因此每个彩票中心下载程序至少运行一个goroutine。

如何播放和暂停执行goroutine?

使用通道,我们可以播放和暂停执行goroutine。通道通过充当goroutine之间的管道来处理此通信。

从Goroutines捕获值

从goroutine中获取值的最自然的方法是通道。通道是连接并发goroutine的管道。您可以将值从一个goroutine发送到通道,然后将这些值接收到另一个goroutine或在同步函数中。

如何在彩票中心下载中创建goroutine?

在每次调用函数responseSize之前添加了go关键字。三个responseSize goroutine程序同时启动,并且同时进行了三个对http.Get的调用。该程序不会等到一个响应返回后才发出下一个请求。结果,使用goroutines可以更快地打印出三种响应大小。

如何使用互斥锁定义代码的关键部分并解决竞争条件?

互斥锁用于在代码周围创建关键部分,以确保一次只能有一个goroutine可以执行该代码部分。