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. Day04_网络爬虫图片收获

    #所需模块 requests .Beautifulsoup.urllib 1. response = requests.get('www.baidu.com')  #获取网站响应 2.html = r ...

  2. mysql 数据库查看表的信息

    查看正在改动的数据库: 1. select database(); 2. status;   查看表的结构: desc table_name show columns from table_name ...

  3. Java——string类型与date类型之间的转化

    String类型转化为Date类型 方法一 Date date=new Date("2019-01-25"); 方法二 String =(new SimpleDateFormat( ...

  4. 联想Y410P在Ubuntu系统下开关机及插耳机破音“啪啪”的解决办法

    转载自:https://blog.csdn.net/YiKangJ/article/details/81239556 1.解决开关机“啪啪响”: options snd-hda-intel model ...

  5. penn treebank的说明,包括很多语法知识

    penn数据库说明 http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.9.8216&rep=rep1&type=pdf

  6. Spring事务<tx:annotation-driven/>的理解(Controller使用@Transactional)

    在使用Spring的时候,配置文件中我们经常看到 annotation-driven 这样的注解,其含义就是支持注解,一般根据前缀 tx.mvc 等也能很直白的理解出来分别的作用. <tx:an ...

  7. 渗透测试学习 三、Linux基础

    Linux发行版本  内核+应用程序  打包在一起 一.优点: 完全免费 完全兼容POSIX 1.0标准 多用户,多任务 良好的界面 可靠安全稳定的性能 支持多种平台 丰富的网络功能 安全性更好(针对 ...

  8. redis过期机制

    Redis会自己回收清理不用的数据吗? 如果能,那如何配置? 如果不能,如何防止数据累加后大量占用存储空间的问题? 之前一直接触Redis不是很深入,最近项目当中遇到一个需求场景,需要清空一些存放在R ...

  9. 使用OpenLDAP部署目录服务

  10. Java(日期、随机数、系统工具类)

    Date类 一般用于获取时间 Date date1 = new Date();//获取当前系统时间 Date date2 = new Date(10000);//获取从标准基准时间起10000毫秒的时 ...