Func将不会运行; 增量通道

I'm writing a function where I'm trying to increment a channel. In a much larger program, this is not working and it actually hangs on a line that looks like:

current = <-channel

The go funcs are running, but the program seems to halt on this line.

I tried to write a smaller SSCCE, but now I'm having a different problem. Here it is:

package main                                                                    

import (                                                                        
    "fmt"                                                                       
)                                                                               

func main() {                                                                   
    count := make(chan int)                                                     

    go func(count chan int) {                                                   
        current := 0                                                            
        for {                                                                   
            current = <-count                                                   
            current++                                                           
            count <- current                                                    
            fmt.Println(count)                                                  
        }                                                                       
    }(count)                                                                    
}

However, in the above the go func does not actually seem to be called at all. If I put a fmt.Println statement before for {, it does not print out. If I put fmt.Println statements before or after they go func block, they will both print out.

  1. Why does the self-calling block in the above example not seem to run at all?
  2. If it were running, why would it block on current = <-count? How could I properly increment the channel?

I can't answer the first one issue without more info. The code you did show has two issues. First, the program exits after the goroutine is started. The second issue is that the goroutine is waiting for something to be sent to count, if you receive from the count channel it will not deadlock.

Here is an example showing the deadlock (http://play.golang.org/p/cRgjZt7U2A):

package main

import (
    "fmt"
)

func main() {
    count := make(chan int)

    go func() {
        current := 0
        for {
            current = <-count
            current++
            count <- current
            fmt.Println(count)
        }
    }()
    fmt.Println(<-count)
}

Here is an example of it working the way I think you are expecting (http://play.golang.org/p/QQnRpCDODu)

package main

import (
    "fmt"
)

func main() {
    count := make(chan int)

    go func() {
        current := 0
        for {
            current = <-count
            current++
            count <- current
            fmt.Println(count)
        }
    }()
    count <- 1
    fmt.Println(<-count)
}

Channel :- Channel is something that can't store the value. It can only buffer the value so the basic usage is it can send and receive the value. So when you declare count := make(chan int) it does not contain any value. So the statement current = <-count will give you error that all go routines are asleep. Basically channel was design to work as communicator for different go routines which are running on different process and your main function is running on different process.

So your answer to first question is:-

1.Why does the self-calling block in the above example not seem to run at all?

Answer- See the main function you are running has one process and the go routine is running on another process so if your main function gets its execution completed before your go-routine than you will never get result form go-routine because your main thread gets dead after the execution is complete. So i am providing you a web example which is related to your example of incrementing the counter. In this example you will create a server and listen on port 8000.First of all run this example and go in your web browser and type localhost:8000 and it will so you the incrementing counter that channel stores in every buffer. This example will provide you an idea of how channel works.

2.If it were running, why would it block on current = <-count? How could I properly increment the channel?

Answer-You are receiving from the channel but channel does not have anything in its buffer so you will get an error "All go-routines are asleep". First you should transfer value into the channel and correspondingly receive it otherwise it will again go to deadlock.

package main

import (
    "fmt"
    "http"
)


    type webCounter struct {
        count chan int
    }

    func NewCounter() *webCounter {
        counter := new(webCounter)
        counter.count = make(chan int, 1)
        go func() {
            for i:=1 ;; i++ { counter.count <- i }
        }()
        return counter
    }

    func (w *webCounter) ServeHTTP(r http.ResponseWriter, rq *http.Request) {
            if rq.URL.Path != "/" {
            r.WriteHeader(http.StatusNotFound)
            return
        }
        fmt.Fprintf(r, "You are visitor %d", <-w.count)
    }

    func main() {
        http.ListenAndServe(":8000", NewCounter());
}