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. github项目

    一.github项目地址: https://github.com/fairy1231/gitLearning/tree/master 二.github的重要性: Git 是一个快速.可扩展的分布式版本 ...

  2. django学习:一些疑惑

    昨天学习了django的第二天,有一些收获. django的语法很严谨,看上去明明对齐的,但是他却提示说缩进不一致.后来我把前面的空全部删除,全部采用空格,这样就通过了,看样子还是要编程有一个好习惯, ...

  3. 工具提高效率 - iterm2

    快捷键 command + d, command + shift +d 显示所有记录 ITERM默认设置了终端能保留的历史输出行数,在进行调试时特别不方便,一旦输出过多就无法看到完整的历史记录. 在P ...

  4. ArcGIS中的坐标系:基本概念和常用操作(二)

    关于坐标系,上次的内容还没有结束. 上次已经解释清楚关于投影坐标系和地理坐标系的区别了,它们在实际应用上也有诸多不同. 下面这张图应该比较清晰 我们经常能发现,当计算面积时,提示面积已禁用,原因就在于 ...

  5. 51单片机---点亮一个LED灯

    1 程序源码 #include <REGX52.H> `包含51单片机的头文件` sbit led = P0^0; int main(void) { while(1) { led = 1; ...

  6. vue 监听手机键盘是否弹出及input是否聚焦成功

    //定义移动端类型 function pageStats() { let u = navigator.userAgent, app = navigator.appVersion; let obj = ...

  7. MHA-Atlas-MySQL高可用集群

    主机名映射   [root@localhost ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 loca ...

  8. 第二次Scrum冲刺——Life in CCSU

    第二次Scrum冲刺——Life in CCSU 一. 第二次Scrum任务 继续上一次冲刺的内容,这次完成论坛部分. 二. 用户故事 用户输入账号.密码: 用户点击论坛部分: 系统显示帖子: 用户选 ...

  9. 汇编实验2(又是作业emm)

    实验任务:学会使用debug 1.使用Debug,将程序段写入内存: 首先对0021:0000~0021:000F的内存赋值 这里我赋的值是 11 12 13 14 15 16 17 18 输入mov ...

  10. Java_04循环结构

    1.while 循环结构 格式: while(循环条件){ } 关键字 while 后的小括号中的内容是循环条件.循环条件是一个表达式,值为布尔类型. { }大括号中的语句统称为循环操作,又称为循环体 ...