zoukankan      html  css  js  c++  java
  • Questions in golang

    I list some questions in Go in my daily life and the corresponding answer.

    QA 1. the reader <-channel will be blocked until the writer write the channel?

    in gocrawl, the worker reads the channel as follows

    1 select {
    2     case <-this.stop:
    3             this.logFunc(LogInfo, "stop signal received.")
    4         return
    5     default:
    6         // Nothing, just continue...
    7 }

    However, I can't find the code where the crawler writes the chanel but only to find code illustrated below

     1 for {
     2     // By checking this after each channel reception, there is a bug if the worker
     3     // wants to reenqueue following an error or a redirection. The pushPopRefCount
     4     // temporarily gets to zero before the new URL is enqueued. Check the length
     5     // of the enqueue channel to see if this is really over, or just this temporary
     6     // state.
     7     //
     8     // Check if refcount is zero - MUST be before the select statement, so that if
     9     // no valid seeds are enqueued, the crawler stops.
    10     if this.pushPopRefCount == 0 && len(this.enqueue) == 0 {
    11         this.logFunc(LogInfo, "sending STOP signals...")
    12         close(this.stop)
    13         return nil
    14     }
    15         ......

    I am puzzed about it and wonder does close chanel will make <-channel work. So I make a test ad demenstrated

     1 package main
     2 
     3 import (
     4     "fmt"
     5     "sync"
     6     "time"
     7 )
     8 
     9 func worker(wg *sync.WaitGroup, c <-chan int) {
    10     fmt.Println("begin worker")
    11 
    12     time.Sleep(1e9)
    13     temp, ok := <-c
    14     fmt.Printf("read singal : %d and ok= %t 
    ", temp, ok)
    15     wg.Done()
    16 
    17     fmt.Println("end worker")
    18 }
    19 
    20 func main() {
    21     fmt.Println("begin main")
    22 
    23     var wg sync.WaitGroup
    24     wg.Add(1)
    25 
    26     cint := make(chan int, 1)
    27     go worker(&wg, cint)
    28     time.Sleep(3e9)
    29     fmt.Println("close channel in main")
    30     close(cint)
    31 
    32     wg.Wait()
    33 
    34     fmt.Println("end main")
    35 }

    the result is

    conclusion:

    if the writter calls close(channel), the reader with expression v, ok :=  <-channel will get v=0 and ok=false.

    ok= false means the channel is closed.

    the writer closing the channel makes the reader "read" the value 0 from the channel.

    after further thought, I find that close(channel) boardcast the signal to all the readers, which is a good mechanism. 

    in the case of gocrawler, the master can boardcast the "stop" signal to all its workers just use only one chan "stop chan struct{}" instead of using "map[host] chan struct{}" for each of the worker.

  • 相关阅读:
    EXTJS 的PagingToolbar.js
    extjs之gridpanel完全操作(事件)
    Asp.net的服务器推技术 (Server Push) .NET
    Extjs 右下角弹出框 可弹出多个 冒泡小窗体
    Web IM技术简介
    iphone 开发图片显示圆角效果
    linux 修改IP, DNS 命令
    Mysql Data目录生成大量mysqlbin.****
    linux下查看内存使用情况
    rpm卸载mysql
  • 原文地址:https://www.cnblogs.com/harrysun/p/3828908.html
Copyright © 2011-2022 走看看