<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>waimv.com &#187; go</title>
	<atom:link href="http://www.waimv.com/category/go/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.waimv.com</link>
	<description></description>
	<lastBuildDate>Fri, 09 Nov 2018 10:41:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>go里面select-case和time.Ticker的使用注意事项</title>
		<link>http://www.waimv.com/go/334/</link>
		<comments>http://www.waimv.com/go/334/#comments</comments>
		<pubDate>Wed, 19 Sep 2018 11:53:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[go]]></category>
		<category><![CDATA[golang]]></category>

		<guid isPermaLink="false">http://www.waimv.com/?p=334</guid>
		<description><![CDATA[package main import ( "fmt" "runtime" "time" ) func init() { runtime.GOMAXPROCS(runtime.NumCPU()) } func main() { ch := make(chan int, 1024) go func(ch chan int) { for { val := &#60;-ch fmt.Printf("val:%d\n", val) } }(ch) tick := time.NewTicker(1 * time.Second) for i := 0; i &#60; 20; i++ { select { case ch &#60;- i: [...]]]></description>
			<content:encoded><![CDATA[<pre>package main

import (
	"fmt"
	"runtime"
	"time"
)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
}

func main() {
	ch := make(chan int, 1024)
	go func(ch chan int) {
		for {
			val := &lt;-ch
			fmt.Printf("val:%d\n", val)
		}
	}(ch)

	tick := time.NewTicker(1 * time.Second)
	for i := 0; i &lt; 20; i++ {
		select {
		case ch &lt;- i:
		case &lt;-tick.C:
			fmt.Printf("%d: case &lt;-tick.C\n", i)
		}	

		time.Sleep(200 * time.Millisecond)
	}
	close(ch)
	tick.Stop()
}</pre>
<pre></pre>
<pre>输出如下:
 

 
<pre>val:0
val:1
val:2
val:3
val:4
val:5
6: case &lt;-tick.C
val:7
val:8
val:9
10: case &lt;-tick.C
val:11
val:12
val:13
val:14
15: case &lt;-tick.C
val:16
val:17
val:18
val:19</pre>
<pre></pre>
<pre>
问题出在这个select里面：

select {
case ch &lt;- i:
case &lt;-tick.C:
fmt.Printf("%d: case &lt;-tick.C\n", i)
}

 
当两个case条件都满足的时候，运行时系统会通过一个伪随机的算法决定哪个case将会被执行
所以当tick.C条件满足的那个循环，有某种概率造成ch&lt;-i没有发送(虽然通道两端没有阻塞，满足发送条件)

解决方案1: 一旦tick.C随机的case被随机到，就多执行一次ch&lt;-i (不体面，如果有多个case就不通用了)
select {
case ch &lt;- i:
case &lt;-tick.C:
fmt.Printf("%d: case &lt;-tick.C\n", i)
ch &lt;- i
}

解决方案2: 将tick.C的case单独放到一个select里面，并加入一个default（保证不阻塞）
select {
case ch &lt;- i:
}
select {
case &lt;-tick.C:
fmt.Printf("%d: case &lt;-tick.C\n", i)
default:
}
 

两种解决方案的输出都是希望的结果：

 
<pre>val:0
val:1
val:2
val:3
val:4
5: case &lt;-tick.C
val:5
val:6
val:7
val:8
val:9
10: case &lt;-tick.C
val:10
val:11
val:12
val:13
val:14
15: case &lt;-tick.C
val:15
val:16
val:17
val:18
val:19</pre>
</pre>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.waimv.com/go/334/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
