golang里,在for循环里面起协程,如下代码。会输出for循环的最后一个数,或者参杂有不确定的其他数字。
原因如下:golang是值拷贝传递。for循环很快,协程创建需要的时间大于for循环的时间。因为协程创建 需要进行 堆栈分配,上下文准备,以及与内核态的线程进行映射工作等。所以在协程创建好后,大家同时去访问tmp变量,这个时候 tmp 就被多个协程共享了,导致取到的值都一样了。
解决方案:就是使用golang的闭包函数。给匿名函数增加入参,因为是值传递,所以每次for创建一个协程的时候,会拷贝一份tmp传到这个协程里面去,这样就可以实现0-9的数字打印了。修改后的代码和实验结果也在下面。
所以在使用协程的时候,需要注意,尽量不要用外面的值,而是改为用闭包这种。