gpt4 book ai didi

go - 使用golang的goroutine如何实现计数器?

转载 作者:IT王子 更新时间:2023-10-29 01:14:26 38 4
gpt4 key购买 nike

我正在尝试制作一个具有推送和弹出功能的队列结构。

我需要使用 10 个线程推送和另外 10 个线程弹出数据,就像我在下面的代码中所做的那样。

问题:

  1. 我需要打印出我插入/弹出了多少,但我不知道该怎么做。
  2. 有什么方法可以加速我的代码吗?代码对我来说太慢了。
package main

import (
"runtime"
"time"
)

const (
DATA_SIZE_PER_THREAD = 10000000
)

type Queue struct {
records string
}


func (self Queue) push(record chan interface{}) {
// need push counter
record <- time.Now()
}

func (self Queue) pop(record chan interface{}) {
// need pop counter
<- record
}

func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
//record chan
record := make(chan interface{},1000000)
//finish flag chan
finish := make(chan bool)
queue := new(Queue)
for i:=0; i<10; i++ {
go func() {
for j:=0; j<DATA_SIZE_PER_THREAD; j++ {
queue.push(record)
}
finish<-true
}()
}
for i:=0; i<10; i++ {
go func() {
for j:=0; j<DATA_SIZE_PER_THREAD; j++ {
queue.pop(record)
}
finish<-true
}()
}
for i:=0; i<20; i++ {
<-finish
}
}

最佳答案

有几件事你应该解决。

  • Queue 类型的方法应该有指针接收器。否则,每个方法调用将创建当前队列类型的副本,对队列字段的任何更改都将不会持续超出方法调用本身。

  • 等待所有例程完成,可以使用 sync.WaitGroup 完成。这个正是它的设计目的。

  • 在队列类型中维护一个线程安全的推送/弹出计数器可以通过使用 sync/atomic 包。

就速度而言,根据您的示例,我不太确定您要达到的目标。如果您稍微详细说明一下,可能会出现任何优化。

这是我根据您的代码修改的示例:

package main

import (
"log"
"runtime"
"sync"
"sync/atomic"
"time"
)

const SizePerThread = 10000000

type Queue struct {
records string
count int64
}

func (q *Queue) push(record chan interface{}) {
record <- time.Now()

newcount := atomic.AddInt64(&q.count, 1)
log.Printf("Push: %d", newcount)
}

func (q *Queue) pop(record chan interface{}) {
<-record

newcount := atomic.AddInt64(&q.count, -1)
log.Printf("Pop: %d", newcount)
}

func main() {
var wg sync.WaitGroup

runtime.GOMAXPROCS(runtime.NumCPU())

record := make(chan interface{}, 1000000)
queue := new(Queue)

// We are launching 20 goroutines.
// Let the waitgroup know it should wait for as many
// of them to finish.
wg.Add(20)

for i := 0; i < 10; i++ {
go func() {
defer wg.Done()

for j := 0; j < SizePerThread; j++ {
queue.push(record)
}
}()

go func() {
defer wg.Done()

for j := 0; j < SizePerThread; j++ {
queue.pop(record)
}
}()
}

// Wait for all goroutines to finish.
wg.Wait()
}

关于go - 使用golang的goroutine如何实现计数器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12265813/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com