为了账号安全,请及时绑定邮箱和手机立即绑定

有一个go语言的问题不是很理解,关于以下channel的问题

有一个go语言的问题不是很理解,关于以下channel的问题

慕村9548890 2021-06-07 11:07:44
package mainimport "fmt"import "os"func Count(ch chan int, i int){ ch <- i file, err := os.OpenFile("data.dat",os.O_CREATE|os.O_APPEND,0777) if err !=nil{ fmt.Println("xxx") return } str := "abc" num,_ := file.WriteString(str) defer file.Close() fmt.Println(num)}func main(){ chs := make([]chan int, 10) for i:=0;i<10;i++ { chs[i] = make(chan int) go Count(chs[i], i) } for _, ch:= range(chs) { num:= <-ch fmt.Print(num) } fmt.Print("\n")}Count方法中字符串怎么写不进去?为什么Count方法中的打印就只打印一次?chs中明显写进了10次值.......小白求大神解答................................
查看完整描述

2 回答

?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

第一个问题,打开文件应添加"|os.O_WRONLY"
file, err := os.OpenFile("data.dat",os.O_CREATE|os.O_APPEND|os.O_WRONLY,0777)
第二个问题,将Count方法中的 "ch<-i"放到方法的最后一行就可以了。
因为一旦“ch<-i"执行了,main方法中的 "<-ch"就会执行通过当所有的"<-ch"执行完后程序就结束了。但这时Count的线程方法还来不及执行完(打开文件的速度相对较慢),所以仅仅执行一次文件操作就结束了

查看完整回答
反对 回复 2021-06-15
?
跃然一笑

TA贡献1826条经验 获得超6个赞

可以先试想下运行结果。其结果就是,没有任何输出,程序直接就结束了。我的理解:因为这是个缓冲的channel(var c = make(chan int,3)),所以存的优先级会高,如果存入缓冲的不足三个,那就等下去(名词叫阻塞),等到程序都结束了。这里要好好理解阻塞的含义。刚开始我以为阻塞只是阻止了channel变量的读取,后来试了几次才知道,所谓的阻塞,说白了就是什么都不干了,就等着某个条件满足之后才会有事件的执行。
  然后改变参数或者是做一些比较小的改动,看程序的运行结果是否会发生变化。在16行后面再增加两个存值操作,c<-11 ;c<-12数值是多少无所谓,因为就只有一次取,取到的肯定是存进去的第一个值。可以猜一下这次的运行结果。这次,跟原来一样,还是没有输出,因为三次存操作之后,阻塞就解开了,开始执行取操作,但是取完之后缓冲中又不足三个了,没办法,还得阻塞,一直等到了程序结束,hello world被漫长的等待覆盖了。再增加一个存操作,就得到了结果,3 helloworld。过程大致为,当三个存满了之后,阻塞被解除了,去执行一个goroutine,即进行了一次取操作,输出3,取完之后又被阻塞,然后又存了一个,阻塞解除,执行后面的操作,输出了hello world.

查看完整回答
反对 回复 2021-06-15
  • 2 回答
  • 0 关注
  • 212 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信