dsn5510 2012-09-07 08:18
浏览 1
已采纳

我的golang代码怎么了? [重复]

Possible Duplicate:
Why my golang lock free queue always stuck there?

Here's my whole source code :

package main

import (
    "sync/atomic"
    "unsafe"
    "sync"
    "fmt"
    "time"
    "runtime"
)

const (
    MAX_DATA_SIZE = 100
)

// lock free queue
type Queue struct {
    head unsafe.Pointer
    tail unsafe.Pointer
}
// one node in queue
type Node struct {
    val interface{}
    next unsafe.Pointer
}
// constructor
func New() (q *Queue) {
    queue := new(Queue)
    queue.head = unsafe.Pointer(new(Node))
    queue.tail = queue.head
    return queue
}
// queue functions
func (self *Queue) enQueue(val interface{}) {
    newValue := unsafe.Pointer(&Node{val: val, next: nil})
    var tail,next unsafe.Pointer
    for {
        tail = self.tail
        next = ((*Node)(tail)).next
        if atomic.CompareAndSwapPointer(&next, nil, newValue) {
            atomic.CompareAndSwapPointer(&self.tail, tail, newValue)
            break
        }else{
            for next != nil {
                tail = next
            }
        }
    }
}

func (self *Queue) deQueue() (val interface{}, success bool){
    var head,next unsafe.Pointer
    for {
        head = self.head
        next = ((*Node)(head)).next
        if next == nil {
            return nil, false
        }else {
            if atomic.CompareAndSwapPointer(&(self.head), head, next) {
                val = ((*Node)(next)).val
                return val, true
            }
        }
    }
    return nil, false
}

func main() {
    //runtime.GOMAXPROCS(runtime.NumCPU())
    fmt.Println(runtime.GOMAXPROCS(-1))
    var wg sync.WaitGroup
    wg.Add(20)
    queue := New()
    for i := 0; i < 10; i++ {
        go func() {
            defer wg.Done()
            for j := 0; j < MAX_DATA_SIZE; j++ {
                t := time.Now()
                fmt.Println("enqueue111")
                fmt.Println("enq = ", t)
                fmt.Println("enqueue222")
                queue.enQueue(t)
            }
        }()
    }

    for i := 0; i < 10; i++ {
        go func() {
            ok := false
            var val interface{}
            defer wg.Done()
            for j := 0; j < MAX_DATA_SIZE; j++ {
                val,ok = queue.deQueue()
                for !ok {
                    val,ok = queue.deQueue()
                }
                fmt.Println("deq = ",val)
            }
        }()
    }

    wg.Wait()
}

The code is stucked at fmt.Println("enq = ", t) but i don't know why, it's so weird.

  • 写回答

2条回答 默认 最新

  • dongyun7571 2012-09-07 18:04
    关注

    deQueue is looping infinitely on the fail case, which is blocking the CPU. Goroutines don't yield while doing CPU work. GOMAXPROCS needs to be >= 2 to get CPU parallelism.

    just for kicks, here's a threadsafe, nonblocking queue implementation using higher-order channels: https://gist.github.com/3668150

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度