我正在尝试创建一个具有推送和弹出功能的队列结构。
我需要使用10个线程推送和另外10个线程弹出数据,就像我在下面的代码中所做的那样。
问题: 我需要打印出我有多少推/弹,但我不知道该怎么做。 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
}
}
答案 0 :(得分:11)
你应该解决一些问题。
Queue类型的方法应该有指针接收器。否则,每一种方法 call将创建当前队列类型的副本,并对队列字段进行任何更改 不要超出方法调用本身。
等待所有例程完成,可以使用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()
}
答案 1 :(得分:-5)
对问题1的回答:正如jimt所建议的那样,sync / atomic具有原子更新计数器的功能,这可能对你有用。
回答问题2:减少DATA_SIZE_PER_THREAD的值,或者更好的是,使用程序
package main
func main() {}
以更高效的方式生成与程序相同的输出。
说真的,我知道你写了一个小程序来探索一些概念。但是,您的程序包含许多问题。现在不是担心速度的时候,是时候学习一些基本概念了。