`
DarkWingBoy
  • 浏览: 52295 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
社区版块
存档分类
最新评论

golang之路-并发编程小记(1)

 
阅读更多

学习了go的基本的并发变成模式,思路就是一个用通信来共享数据,而并不是像java一样共享内存来通讯。go采用了用channel来传递消息,每一个协程持有一个信道,当信道可用时便可以读写数据,各信道间的处理数据互不影响。回想一下java中的并发编程,通常我们是因为操作一个数据而采用多线程并发访问,比较明显的是更新cache中的key对应的value.

让我更是欢喜的时在golang中提供了sync.Once这个神器,从此做系统级的开关不再苦恼,天然的保证了就算多个协程并发的情况下也只有一个协程执行once.Do(func()),其他的协程阻塞。你再想想java里面完成一个系统级初始化,做到并发安全且一次,你要搞一个boolean、再搞把锁,再写逻辑,神啊想想头都大了。

下面是我的小尝试,你可以试试

 

package main

import (
	"fmt"
	"sync"
	"time"
)

var counter int = 0

func main() {
	chls := make([]chan int, 10)
	for i := 0; i < 10; i++ {

		chls[i] = make(chan int)
		go addCounter(chls[i])

	}

	for _, val := range chls {
		counter += <-val
	}

	fmt.Println("---结果是:", counter)

	//设置一个超时的chan,没有阻塞读超时,写超时,可由程序创建chan来判定是否有超时写入
	timeout := make(chan bool, 1)
	subChn := chls[:2]
	for i := 0; i < 2; i++ {
		go timeoutAdd(i, subChn[i], timeout)
	}

	countDonw := 2
	for {
		select {
		case <-subChn[0]:
			fmt.Println("not time out ")
			countDonw--
		case <-timeout:
			fmt.Println("time out ")
			countDonw--

		}

		if countDonw <= 0 {
			break
		}
	}

	//关闭channel
	for idx, ch := range chls {
		close(ch)
		_, ok := <-ch
		if !ok {
			fmt.Println("close channel ", idx)
		}
	}

	// //单向读channel
	// onedirchl := make(<-chan int)
	// //我来试试写操作,会有什么现象呢
	// //go 会报invalid operation: onedirchl <- 1 (send to receive-only type <-chan int)
	// onedirchl <- close(onedirchl)

	//全局唯一性操作,大爱啊,想想java在做系统初始化只需要执行一次并且是多线程并发情况下的代码怎么写?
	//Lock ?全局boolean的开关,我的神啊,复杂

	var once sync.Once

	completeChan := []chan bool{make(chan bool, 1), make(chan bool, 1)}

	//注意啊这里一定要传入指针,不然会是once的一个副本
	go initConifg(&once, func() {
		fmt.Println("我是第一个初始化的channel!")
		completeChan[0] <- true
	})

	go initConifg(&once, func() {
		fmt.Println("我是第二个完成初始化的channel!")
		completeChan[1] <- true
	})

	for _, ch := range completeChan {
		<-ch
		close(ch)
	}

}

func initConifg(once *sync.Once, handler func()) {
	once.Do(func() {
		time.Sleep(5e9)
		fmt.Println("我这是初始化!,我等待了5S完成")
	})

	handler()

}

func timeoutAdd(index int, chl chan int, timeout chan bool) {
	if index%2 != 0 {
		time.Sleep(5e9)
		fmt.Println("模拟超时了")
		timeout <- true
	} else {
		fmt.Println("正常输出..")
		chl <- 1
	}

}

func addCounter(chl chan int) {
	chl <- 1
	fmt.Println("countting")

}

 http://blackbeans.iteye.com/blog/1730314

分享到:
评论

相关推荐

    go-toolset-7-golang-bin-1.8.3-4.el7.x86_64.rpm

    官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装

    开源项目-jdevelop-golang-rpi-extras.zip

    综上所述,“jdevelop-golang-rpi-extras”项目涵盖了Go语言编程、树莓派硬件开发、RFID技术、并发编程等多个IT领域的知识点,为开发者提供了一套完整的RFID读取解决方案。通过学习这个项目,开发者可以提升自己在...

    golang-linux-arm64-sdk

    2. 并发编程:Go语言的goroutine和channel是其并发模型的核心,通过它们,开发者可以轻松实现多任务并行处理,充分利用ARM64架构的多核优势。 3. 性能调优:利用Go的内置性能分析工具,如`pprof`,可以对ARM64上的...

    Go-Golang编程语言的并发性跟踪和可视化工具

    Go-Golang编程语言以其高效的并发模型闻名,它利用了CSP(Communicating Sequential Processes)的概念,通过goroutines和channels来实现。在这个标题为“Go-Golang编程语言的并发性跟踪和可视化工具”的主题中,...

    Java语言写的围棋小游戏 半成品A Go game written in golang(Semi-finished).zip

    半成品A Go game written in golang(Semi-finished).zip Java语言写的围棋小游戏。半成品A Go game written in golang(Semi-finished).zip Java语言写的围棋小游戏。半成品A Go game written in golang(Semi-...

    开源项目-johnnadratowski-golang-neo4j-bolt-driver.zip

    开源项目-johnnadratowski-golang-neo4j-bolt-driver.zip是一个专注于Go语言的开源项目,由johnnadratowski开发,旨在提供对Neo4J数据库的Bolt协议支持。这个驱动程序使得Go开发者能够高效、稳定地与Neo4J图形数据库...

    golang-bin-1.17.2-2.module_el8.6.0+963+7827afaa.x86_64.rpm

    官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装

    golang-stats-api-handler, Golang cpu,内存,gc等信息api处理程序.zip

    golang-stats-api-handler, Golang cpu,内存,gc等信息api处理程序 golang-stats-api-handlerGolang cpu,内存,gc等信息api处理程序。 安装go get github.com/fukata/golang-stats-api-handler示

    golang-misc-1.16.1-3.module_el8.5.0+762+a2d12c29.noarch.rpm

    官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装

    开源项目-NanXiao-golang-101-hacks.zip

    1. **并发编程**:Go语言以其内置的goroutine和channel特性,使得并发编程变得简单而高效。在本项目中,你可以找到关于如何创建和管理goroutine,以及如何利用channel进行同步和通信的示例代码。 2. **类型系统**:...

    golang-crawler-project-codeSource.zip

    总结,`golang-crawler-project-codeSource.zip`提供了一个完整的Go语言爬虫项目实例,通过学习其源码,我们可以了解Go语言在网络爬虫领域的应用,包括网络请求、HTML解析、并发处理和数据存储等方面的知识。...

    Golang_Puzzlers-春节主题资源

    Golang的并发模式特别受欢迎,它通过goroutines来实现并发,这些goroutines比传统的线程消耗更少的资源,使得并发编程更加轻量级。Golang的另一个特点是它的标准库,这个库经过精心设计,可以方便地进行网络和系统...

    开源项目-dkondratovych-golang-ua-meetup.zip

    开源项目-dkondratovych-golang-ua-meetup.zip,Presentation about Context in Go 1.7. Review, examples, thoughts.

    开源项目-alaska-golang-ref-sheet.zip

    开源项目-alaska-golang-ref-sheet.zip,alaska/golang-ref-sheet: A golang quick reference sheet. Your one stop concurrency shop!

    golang-simple-tool-day08.rar

    这可能包括但不限于Go语言的基本语法、数据结构、控制流程、函数、并发编程、错误处理、包管理和测试等。在教程的第八部分,学习者可能会学习到更高级的Go语言特性,比如网络编程、数据库交互、甚至可能涉及到与Web...

    最新intellij ieda golang 插件2013-11-27日编译

    最新intellij ieda golang 插件2013-11-27日编译

    golang.org-master

    而`sync`和`context`包则是Go语言并发编程的关键,它们提供了互斥锁、通道和上下文管理等工具。 除此之外,golang.org包还包含了`cmd`目录,这是Go语言的编译器、链接器以及其他命令行工具的源代码。通过研究`cmd/...

    Api-golang-gin-realworld-example-app.zip

    Api-golang-gin-realworld-example-app.zip,使用golang gingolang/gin代码库构建的示例性真实世界应用程序,包含遵循真实世界规范和api的真实世界示例(crud、auth、高级模式等)。,一个api可以被认为是多个软件设备...

    golang-github-pmezard-go-difflib-unit-test-devel-0-0.9

    golang-github-pmezard-go-difflib-unit-test-devel-0-0.9.git792786c.1.el7.x86_64 官方离线安装包,亲测可用

Global site tag (gtag.js) - Google Analytics