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. Javascript仿贪吃蛇出现Bug的反思

    bug现象:    图一

  2. 采用NoteExpress参考文献导入和导出

    1.NoteExpress使用 该软件分为企业版和个人版,但目前看来个人版已经不能用了,我用的是我们学校购买的软件,感觉还是很方便的. (1)首先建立数据库: (2)可以通过导入原文选项将下载好的文章 ...

  3. python学习1---列表、矩阵、数组

    1.列表与数组区别 numpy数组的所有元素类型是相同的,而列表的元素类型是任意的. 2.numpy数组与矩阵区别 矩阵必须是二维的,数组可以是多维的,matrix是array的一个分支. matri ...

  4. 连接mysql用mysql_connect不能连接

    用mysqli_connect就可以解决. mysqli_array()有连个参数,第一个是连接mysql名. php遇到这个警告Warning: Use of undefined constant ...

  5. Linux与Windows的几点区别

    echo $PATH 回显Linux环境变量PATH的值,Linux下的环境变量必须大写echo %path% 回显Windows环境变量path的值 export PATH=/usr/local/t ...

  6. JavaScript 之存取器属性

    首先介绍一下此篇随笔的主角: Object.getOwnPropertyDescriptor 和 Object.getOwnPropertyDescriptors 通过这两个api,可以访问除 nul ...

  7. openpyxl工具总结

    1.openpyxl使用 涉及到单元格合并.赋值 ''' .格式转换 raw_data create_data boolean Bool uint8 UInt8 int8 Int8 uint16 UI ...

  8. EXCEL 批量添加单元格名称

    在EXCEL单元格的值填入想为其设置的名称之后,调整下述代码的begin_line,begin_column,end_line,end_column的值,执行此宏,可用于批量为单元格设置名称. (注: ...

  9. 自定义事件——Event和CustomEvent

    之前在学习自定义事件时,在MDN的Event.initEvent()页面顶端有写:该特性已从Web标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性. 作 ...

  10. EF框架引用问题

    安装EF框架时,从NuGet上安装 EF 安装完成以后仍然报错误 这个错误  是因为EF实体数据模型未引用System.data.entity  这个DLL ,记一下以防止以后忘记