当前位置: 首页 > news >正文

大型网站建设一般多少钱百度seo排名优化公司

大型网站建设一般多少钱,百度seo排名优化公司,回到明朝当王爷txt下载,如何自己做加盟网站GO语言网络编程(并发编程)Sync 1、Sync 1.1.1. sync.WaitGroup 在代码中生硬的使用time.Sleep肯定是不合适的,Go语言中可以使用sync.WaitGroup来实现并发任务的同步。 sync.WaitGroup有以下几个方法: 方法名 功能 (wg * WaitG…

GO语言网络编程(并发编程)Sync

1、Sync

1.1.1. sync.WaitGroup

在代码中生硬的使用time.Sleep肯定是不合适的,Go语言中可以使用sync.WaitGroup来实现并发任务的同步。 sync.WaitGroup有以下几个方法:

方法名 功能
(wg * WaitGroup) Add(delta int) 计数器+delta
(wg *WaitGroup) Done() 计数器-1
(wg *WaitGroup) Wait() 阻塞直到计数器变为0
sync.WaitGroup内部维护着一个计数器,计数器的值可以增加和减少。例如当我们启动了N 个并发任务时,就将计数器值增加N。每个任务完成时通过调用Done()方法将计数器减1。通过调用Wait()来等待并发任务执行完,当计数器值为0时,表示所有并发任务已经完成。

我们利用sync.WaitGroup将上面的代码优化一下:

var wg sync.WaitGroupfunc hello() {defer wg.Done()fmt.Println("Hello Goroutine!")
}
func main() {wg.Add(1)go hello() // 启动另外一个goroutine去执行hello函数fmt.Println("main goroutine done!")wg.Wait()
}

需要注意sync.WaitGroup是一个结构体,传递的时候要传递指针。

1.1.2 sync.Once

说在前面的话:这是一个进阶知识点。

在编程的很多场景下我们需要确保某些操作在高并发的场景下只执行一次,例如只加载一次配置文件、只关闭一次通道等。

Go语言中的sync包中提供了一个针对只执行一次场景的解决方案–sync.Once。

sync.Once只有一个Do方法,其签名如下:

func (o *Once) Do(f func()) {}

注意:如果要执行的函数f需要传递参数就需要搭配闭包来使用。

加载配置文件示例

延迟一个开销很大的初始化操作到真正用到它的时候再执行是一个很好的实践。因为预先初始化一个变量(比如在init函数中完成初始化)会增加程序的启动耗时,而且有可能实际执行过程中这个变量没有用上,那么这个初始化操作就不是必须要做的。我们来看一个例子:

var icons map[string]image.Imagefunc loadIcons() {icons = map[string]image.Image{"left":  loadIcon("left.png"),"up":    loadIcon("up.png"),"right": loadIcon("right.png"),"down":  loadIcon("down.png"),}
}// Icon 被多个goroutine调用时不是并发安全的
func Icon(name string) image.Image {if icons == nil {loadIcons()}return icons[name]
}

多个goroutine并发调用Icon函数时不是并发安全的,现代的编译器和CPU可能会在保证每个goroutine都满足串行一致的基础上自由地重排访问内存的顺序。loadIcons函数可能会被重排为以下结果:

func loadIcons() {icons = make(map[string]image.Image)icons["left"] = loadIcon("left.png")icons["up"] = loadIcon("up.png")icons["right"] = loadIcon("right.png")icons["down"] = loadIcon("down.png")
}

在这种情况下就会出现即使判断了icons不是nil也不意味着变量初始化完成了。考虑到这种情况,我们能想到的办法就是添加互斥锁,保证初始化icons的时候不会被其他的goroutine操作,但是这样做又会引发性能问题。

使用sync.Once改造的示例代码如下:

var icons map[string]image.Imagevar loadIconsOnce sync.Oncefunc loadIcons() {icons = map[string]image.Image{"left":  loadIcon("left.png"),"up":    loadIcon("up.png"),"right": loadIcon("right.png"),"down":  loadIcon("down.png"),}
}// Icon 是并发安全的
func Icon(name string) image.Image {loadIconsOnce.Do(loadIcons)return icons[name]
}

sync.Once其实内部包含一个互斥锁和一个布尔值,互斥锁保证布尔值和数据的安全,而布尔值用来记录初始化是否完成。这样设计就能保证初始化操作的时候是并发安全的并且初始化操作也不会被执行多次。

1.1.3 sync.Map

Go语言中内置的map不是并发安全的。请看下面的示例:

var m = make(map[string]int)func get(key string) int {return m[key]
}func set(key string, value int) {m[key] = value
}func main() {wg := sync.WaitGroup{}for i := 0; i < 20; i++ {wg.Add(1)go func(n int) {key := strconv.Itoa(n)set(key, n)fmt.Printf("k=:%v,v:=%v\n", key, get(key))wg.Done()}(i)}wg.Wait()
}

上面的代码开启少量几个goroutine的时候可能没什么问题,当并发多了之后执行上面的代码就会报fatal error: concurrent map writes错误。

像这种场景下就需要为map加锁来保证并发的安全性了,Go语言的sync包中提供了一个开箱即用的并发安全版map–sync.Map。开箱即用表示不用像内置的map一样使用make函数初始化就能直接使用。同时sync.Map内置了诸如Store、Load、LoadOrStore、Delete、Range等操作方法。

var m = sync.Map{}func main() {wg := sync.WaitGroup{}for i := 0; i < 20; i++ {wg.Add(1)go func(n int) {key := strconv.Itoa(n)m.Store(key, n)value, _ := m.Load(key)fmt.Printf("k=:%v,v:=%v\n", key, value)wg.Done()}(i)}wg.Wait()
}
http://www.ritt.cn/news/7899.html

相关文章:

  • 自己建一个网站难吗海口seo网络公司
  • 网站建设多少钱一个百度框架户开户渠道
  • 网站站外优化怎么做中国电信视频app下载
  • 企业网络安全设计方案seo服务指什么意思
  • 网站建设seo网络推广自媒体视频发布平台
  • 怎么做扒代码网站南京seo整站优化技术
  • 上海住房与城乡建设部网站文山seo
  • 国内做的比较好的协会网站百度网址安全检测
  • 成都广告公司百度的搜索引擎优化
  • 公司做网站要花多少钱新闻头条最新消息30字
  • 网站与微信西安关键词网站排名
  • 郑州买房三大网站手机游戏性能优化软件
  • 免费做网站平台电商运营seo
  • 电商网站建设济南建网站百度竞价被点击软件盯上
  • 网站建设app手机下载谷歌搜图
  • 手机和pc合一的网站全搜网
  • b2b大型网站建设可以发广告的100个网站
  • 网站用的空间网络seo外包
  • 专业商城网站建设报价如何推广网站链接
  • 中国建设银行2024版本网络优化大师
  • 白鹭引擎做网站2021近期时事新闻热点事件
  • 信誉好的武汉网站建设sem是什么仪器
  • 做室内装修的网站公司个人怎么做网络推广
  • 网站建设步骤及分工谷歌seo博客
  • 做公司网站详细步骤6深圳网站seo优化公司
  • 网站服务合同纠纷调解昆明网站seo优化
  • 东莞市建设培训中心网站门户网站
  • 做化妆品等的网站赵阳竞价培训
  • 备案关闭网站建设影响核心关键词如何优化
  • 网站建设 助力社会组织网站制作平台