Go语言 并发编程

作者:Eric
微信:loveoracle11g

1、创建goroutine

// 并行 是两个队列同时使用两台咖啡机
// 并发 是两个队列交替使用一台咖啡机
package main

import (
    "fmt"
    "time"
)

func newTask() {
    for {
        fmt.Println("this is a newTask")
        time.Sleep(time.Second) // 延时1s
    }
}

func main() {
    go newTask() // 新建一个协程,新建一个任务

    for {
        fmt.Println("this is a main goroutine")
        time.Sleep(time.Second) // 延时1s
    }

}

2、主goroutine先退出

package main

import (
	"fmt"
	"time"
)

// 主协程退出了,其它子协程也要跟着退出
func main() {
	go func() {
		i := 0
		for {
			i++
			fmt.Println("子协程 i =", i)
			time.Sleep(time.Second)
		}
	}()

	i := 0
	for {
		i++
		fmt.Println("main i =", i)
		time.Sleep(time.Second)

		if i == 2 {
			break
		}
	}

}

3、主协程先退出导致子协程没有来得及调用

package main

import (
	"fmt"
	"time"
)

func main() {

	go func() {
		i := 0
		for {
			i++
			fmt.Println("子协程 i =", i)
			time.Sleep(time.Second)
		}
	}()
}

4、Gosched的使用

package main

import "fmt"

func main() {
    go func() {
        for i := 0; i < 5; i++ {
            fmt.Println("Go")
        }
    }()

    for i := 0; i < 2; i++ {
        fmt.Println("hello")
    }
}
package main

import (
	"fmt"
	"runtime"
)

func main() {
	go func() {
		for i := 0; i < 5; i++ {
			fmt.Println("Go")
		}
	}()

	for i := 0; i < 2; i++ {
		// 让出时间片,先让别的协议执行,它执行完毕,再来执行此协程
		runtime.Gosched()
		fmt.Println("hello")
	}
}

5、Goexit的使用

package main

import (
	"fmt"
	"runtime"
)

func test() {
	defer fmt.Println("ccccccccccccccccccccccc")
	// return // 终止此函数
	runtime.Goexit() // 终止所在的协程
	fmt.Println("ddddddddddddddddddddddddddddd")
}

func main() {
	// 创建新建的协程
	go func() {
		fmt.Println("aaaaaaaaaaaaaaaaaaaaaaaaa")

		// 调用了别的函数
		test()
		fmt.Println("bbbbbbbbbbbbbbbbbbbbbbbbb")
	}()

	// 特地写一个死循环,目的不让主协程结束
	for {
	}
}

6、GOMAXPROCS的使用

package main

import (
	"fmt"
	"runtime"
)

func main() {
	// n := runtime.GOMAXPROCS(1) // 指定以1核运算
	n := runtime.GOMAXPROCS(4) // 指定以4核运算
	fmt.Println("n =", n)

	for {
		go fmt.Print(1)
		fmt.Print(0)
	}
}

7、多任务资源竞争问题

package main

import (
	"fmt"
	"time"
)

// 定义一个打印机,参数为字符串,按每个字符打印
// 打印机属于公共资源
func printer(str string) {
	for _, data := range str {
		fmt.Printf("%c", data)
		time.Sleep(time.Second)
	}
	fmt.Printf("\n")
}

func person1() {
	printer("hello")
}

func person2() {
	printer("world")
}

func main() {
	// printer("hello")
	// printer("world")

	// 新建2个协程,代表2个人,2个人同时使用打印机
	go person1()
	go person2()

	// 特地不让主协程结束,死循环
	for {

	}
}

8、通过channel实现同步

package main

import (
	"fmt"
	"time"
)

// 全局变量,创建一个channel
var ch = make(chan int)

// 定义一个打印机,参数为字符串,按每个字符打印
// 打印机属于公共资源
func printer(str string) {
	for _, data := range str {
		fmt.Printf("%c", data)
		time.Sleep(time.Second)
	}
	fmt.Printf("\n")
}

// person1执行完后,才能到person2执行
func person1() {
	printer("hello")
	ch <- 666 //给管道写数据,发送
}

func person2() {
	<-ch // 从管道取数据,接收,如果通道没有数据,他就会阻塞
	printer("world")
}

func main() {
	// printer("hello")
	// printer("world")

	// 新建2个协程,代表2个人,2个人同时使用打印机
	go person1()
	go person2()

	// 特地不让主协程结束,死循环
	for {

	}
}

9、通过channel实现同步和数据交互

package main

import (
	"fmt"
	"time"
)

func main() {
	// 创建channel
	ch := make(chan string)

	defer fmt.Println("主协程也结束了")

	go func() {
		defer fmt.Println("子协程调用完毕")

		for i := 0; i < 2; i++ {
			fmt.Println("子协程 i =", i)
			time.Sleep(time.Second)
		}

		ch <- "我是子协程,工作完毕"
	}()

	str := <-ch // 没有数据前,阻塞
	fmt.Println("str =", str)

}

10、无缓冲channel

package main

import (
	"fmt"
	"time"
)

func main() {
	// 创建channel
	ch := make(chan int, 0)

	// len(ch) 缓存区剩余数据个数
	// cap(ch) 缓冲区大小
	fmt.Printf("len(ch) = %d, cap(ch) = %d\n", len(ch), cap(ch))

	// 新建协程
	go func() {
		for i := 0; i < 3; i++ {
			fmt.Println("子协程:i =", i)
			ch <- i // 往chan写内容
		}
	}()

	// 延时
	time.Sleep(2 * time.Second)
	for i := 0; i < 3; i++ {
		num := <-ch // 读管道中的内容,没有内容前,阻塞
		fmt.Println("num =", num)
	}
}

11、

Go语言 并发编程的更多相关文章

  1. 融云开发漫谈:你是否了解Go语言并发编程的第一要义?

    2007年诞生的Go语言,凭借其近C的执行性能和近解析型语言的开发效率,以及近乎完美的编译速度,席卷全球.Go语言相关书籍也如雨后春笋般涌现,前不久,一本名为<Go语言并发之道>的书籍被翻 ...

  2. Go语言并发编程总结

    转自:http://blog.csdn.net/yue7603835/article/details/44309409 Golang :不要通过共享内存来通信,而应该通过通信来共享内存.这句风靡在Go ...

  3. go语言并发编程

    引言 说到go语言最厉害的是什么就不得不提到并发,并发是什么?,与并发相关的并行又是什么? 并发:同一时间段内执行多个任务 并行:同一时刻执行多个任务 进程.线程与协程 进程: 进程是具有一定独立功能 ...

  4. Go语言并发编程示例 分享(含有源代码)

    GO语言并发示例分享: ppt http://files.cnblogs.com/files/yuhan-TB/GO%E8%AF%AD%E8%A8%80.pptx 代码, 实际就是<<Go ...

  5. Python3 与 C# 并发编程之~ 线程篇

      2.线程篇¶ 在线预览:https://github.lesschina.com/python/base/concurrency/3.并发编程-线程篇.html 示例代码:https://gith ...

  6. 11 go并发编程-上

    其他编程语言并发编程的效果 并发编程可以让开发者实现并行的算法以及编写充分利用多核处理器和多核性能的程序.在当前大部分主流的编程语言里,如C,C++,java等,编写维护和调试并发程序相比单线程程序而 ...

  7. golang:并发编程总结

    并行和并发 并发编程是指在一台处理器上"同时"处理多个任务. 宏观并发:在一段时间内,有多个程序在同时运行. 微观并发:在同一时刻只能有一条指令执行,但多个程序指令被快速的轮换执行 ...

  8. 《Go并发编程实战》读书笔记-初识Go语言

    <Go并发编程实战>读书笔记-初识Go语言 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在讲解怎样用Go语言之前,我们先介绍Go语言的特性,基础概念和标准命令. 一. ...

  9. c++ 11开始语言本身和标准库支持并发编程

    c++ 11开始语言本身和标准库支持并发编程,意味着真正要到编译器从语言和标准库层面开始稳定,估计得到17标准出来.14稳定之后的事情了,根据历史经验,新特性的引入到稳定被广泛采用至少要一个大版本的跨 ...

随机推荐

  1. 元组tuple 可迭代对象

    1. 字符串.元组和列表相互转化 s = 'abcdef' li = ['a','b','c','d'] tu = (1,2,4,9) v = tuple(s) print('v = ',v) w = ...

  2. 输入一个正整数n,计算出[0,n]这些整数中的二进制数没有连续3个1的数字有多少

    输入一个正整数n,计算出[0,n]这些整数中的二进制数没有连续3个1的数字有多少? 例子:输入数字9,则输出结果位9.因为[0-9]中,只有数字7有连续的三个‘1’出现,别的都没有,所以一共有9个数字 ...

  3. NSArray NSMutableArray

    NSArray 或者 NSMUtableArray 去除重复的数据: 原来集合操作可以通过valueForKeyPath来实现的,去重可以一行代码实现: [array valueForKeyPath: ...

  4. Mathematica求微分换元

    [转载请注明出处]http://www.cnblogs.com/mashiqi 2017/12/16 有时我们需要对PDEs中的各项进行变量替换,比如把$\frac{\text{d}}{\text{d ...

  5. 科学计算库Numpy(1)

    Numpy 一,数据结构 数据类型: ndarray import numpy world_alchol = numpy.genfromtxt('world_alchol.txt',delimiter ...

  6. syslog日志打印

    最近syslog出了一次问题,我们配置了不同appname打印到不同文件.现在用不同appname打印log的时候,偶然会混在一起.检查过配置后,觉得不是配置问题,如果是配置问题应该每一条都会打错位置 ...

  7. Java中对Array数组的常用操作

    目录: 声明数组: 初始化数组: 查看数组长度: 遍历数组: int数组转成string数组: 从array中创建arraylist: 数组中是否包含某一个值: 将数组转成set集合: 将数组转成li ...

  8. python中random模块的使用

    import random random.random() 产生0-1间的随机小数 >>> res = random.random() >>> print(res) ...

  9. 用递归方法求n阶勒让德多项式的值

    /* Date: 07/03/19 15:40 Description: 用递归法求n阶勒让德多项式的值      { 1  n=0    Pn(x)= { x  n=1      { ((2n-1) ...

  10. 本博客不再更新和维护,后续文章会在掘金和GitHub发布,感兴趣的小伙伴可以掘金搜索王振宇,谢谢

    本博客不再更新和维护,后续文章会在掘金和GitHub发布,感兴趣的小伙伴可以掘金搜索王振宇,谢谢