go语言中的并发

package main;

import (
        "fmt"
        "runtime"
        "sync"
)

//goruntine奉行通过通信来共享内存,而不是共享内存来通信
//channel是goruntine沟通的桥梁,大都是阻塞同步的
//通过make创建,close关闭
//channel是引用类型
//使用for range来迭代操作channel
//可设置单向或双向通道
//可设置缓存大小,在未被填满前不会发生阻塞

func main() {
        //这里需要设置chan的类型
        ch := make(chan bool);
        go func() {
                fmt.Println("run...");
                ch <- true;
        }();
        //这里是阻塞的,等到匿名函数执行完成,给ch设置为true时
        //这里能读取出数据时,就退出。
        <-ch;

        ch1 := make(chan bool);
        go func() {
                fmt.Println("run...");
                ch1 <- true;
                close(ch1);
        }();
        //对chan进行迭代操作时,必须在某个地方关闭该chan,不然会发生死锁
        for v := range ch1 {
                fmt.Println(v);
        }

        //有缓存是异步的
        ch2 := make(chan bool, 1);
        go func() {
                fmt.Println("run...");
                <-ch2;
        }();
        ch2 <- true;

        //使用多核
        runtime.GOMAXPROCS(runtime.NumCPU());
        ch3 := make(chan bool, 10);
        for i := 0; i < 10; i++ {
                go run(ch3, i);
        }
        //这里读取10次,跟上面go run()执行次数相同
        //保证10次运行都执行完,才退出
        for i:= 0; i < 10; i++ {
                <-ch3;
        }

        //这里创建任务
        wg := sync.WaitGroup{};
        wg.Add(10);
        for i := 0; i < 10; i++ {
                go run2(&wg, i);
        }
        //等待所有任务完成
        wg.Wait();

        //有多个chan时,如何处理
        ch4, ch5 := make(chan int), make(chan string);
        //用于判断是否关闭
        ch6 := make(chan bool);
        go func() {
                for {
                        select {
                        case v, ok := <-ch4:
                                if !ok {
                                        ch6 <- true;
                                        break;
                                }
                                fmt.Println(v);
                        case v, ok := <-ch5:
                                if !ok {
                                        ch6 <- true;
                                        break;
                                }
                                fmt.Println(v);
                        }
                }
        }();

        ch4 <- 1;
        ch4 <- 2;
        ch5 <- "hello";
        ch5 <- "world";

        close(ch4);
        close(ch5);
        //循环读取二次
        for i := 0; i < 2; i++ {
                <-ch6;
        }

}

func run(ch chan bool, ix int) {
        a := 0;
        for i := 1; i < 10000; i++ {
                a += i;
        }
        fmt.Println(ix, a);

        //给chan传递true,说明该run执行结束
        ch <- true;
}

func run2(wg *sync.WaitGroup, ix int) {
        a := 0;
        for i := 1; i < 10000; i++ {
                a += i;
        }
        fmt.Println(ix, a);
        //任务完成
        wg.Done();
}