初级会员
  • 第 6964 位会员
  • huangxianghan
  • huangxianghan@qq.com
  • 2016-12-19 15:23:51

最近发布的主题

    暂无

最近分享的资源

    暂无

最近发布的项目

    暂无

最近的评论

  • 你这个锁效率太低,说是非阻塞锁,但其实你用了两个锁,仍然是阻塞了。仍然执行了一个锁的加锁和解锁操作。 对于这种,应该用原子操作,原子操作是cpu硬件实现的,真正的无阻塞。 实现也很简单: package main import ( "fmt" "sync" "sync/atomic" "time" ) type foo struct { f int32 // 0为解锁状态,1为锁住状态 } func (self *foo) Bong(wg *sync.WaitGroup) { defer wg.Done() //判断是否为0,如果是则更改为1,并返回true,如果不是则不更改,并返回false //判断与更改是原子性操作,由cpu硬件实现,比锁快。 if !atomic.CompareAndSwapInt32(&self.f, 0, 1) { fmt.Println("获取锁失败") return } time.Sleep(time.Second) //停顿一秒 fmt.Println("bong~") //将状态改回0 atomic.StoreInt32(&self.f, 0) } func main() { f := &foo{} wg := &sync.WaitGroup{} wg.Add(4) go f.Bong(wg) go f.Bong(wg) go f.Bong(wg) time.Sleep(time.Second * 2) go f.Bong(wg) wg.Wait() }
  • win64问,无法重现你这个bug,无论我是删掉go:uintptrescapes 这行注释,还是加上这行。我是直接编译成.exe文件再执行的,没用 go run 这种方式。
  • 开来你还是没有理解闭包的精髓,你说的那个功能C# 早10年前就有了,函数里面把变量定义成函数级静态变量,和你说的init B int,一模一样,人家C# 还是可以闭包,为什么,我也不多说,你慢慢思考。我只能提示你,闭包还有很多特殊用法,这些都是较为经典的用法,你文章没有提出,你自己去是思考吧。
  • 不用递归就用广度搜索算法,就是利用列队遍历来代替递归。 代码如下: var QueueEOF = errors.New("queue is emtity") //用数组实现的简单列队 type stringQueue struct { next int data []string } func newStrQueue() *stringQueue { return &stringQueue{data: make([]string, 0, 1024)} } func (que *stringQueue) add(el string) { que.data = append(que.data, el) } func (que *stringQueue) pop() (string, error) { if que.next >= len(que.data) { return "", QueueEOF } nextStr := que.data[que.next] que.next++ return nextStr, nil } //广度搜索算法 func bfsFile(folder string) { var ( path string err error files []os.FileInfo ) //目录遍历队列 que := newStrQueue() //根目录入队 que.add(folder) //循环到列队不再有元素 for { if path, err = que.pop(); err != nil { break } if files, err = ioutil.ReadDir(path); err != nil { break } for _, f := range files { if f.IsDir() { //子目录入队 que.add(path + "/" + f.Name()) } else { //处理文件 //fmt.Println(path + "/" + f.Name()) } } } }
  • 看了下你的代码,我觉得你的代码的意图是,创建一个bool的chan 每个线程结束通知这个通道。 然后再通过遍历这个通道来达到等待所有线程都执行结束的目的。 但是完全不需要用到通道。直接用WaitGroup就行了。 不知道你是否这个意图。至少你代码展现是这个意图。 以下使用WaitGroup的例子。 package main import ( "fmt" "sync" ) func main() { //如果想用和cpu同等数量的线程,这句根本不需要,go默认就是。 //runtime.GOMAXPROCS(runtime.NumCPU()) var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go Go(&wg, i) } wg.Wait() } func Go(wg *sync.WaitGroup, index int) { //defer 的作用不单单是结束才运行,它是保证函数出错了也运行的机制。 //但对性能有影响,如果这函数永远不会发生运行时错误,最好加到末尾。 defer wg.Done() a := 0 for i := 0; i < 10000000; i++ { a += i } fmt.Println(index, a) //wg.Done() }