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

可以做哪些网站友情链接交换

可以做哪些网站,友情链接交换,上海市建设交通工作党委网站,泰安网站建设推广✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/UWz06 📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏…

 ✍个人博客:Pandaconda-CSDN博客

📣专栏地址:http://t.csdnimg.cn/UWz06

📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

16. 什么是 sync.Once?

sync.Once 是 Go 语言中的一个同步原语,用于实现只执行一次的操作。它可以保证在多个 Goroutine 中只执行一次指定的操作,即使这个操作被多次调用。

sync.Once 的使用非常简单,只需要创建一个 sync.Once 类型的变量,然后使用 Do() 方法来指定要执行的操作。Do() 方法会保证指定的操作只会被执行一次,无论它被调用多少次。下面是一个简单的例子:

var once sync.Once
func setup() {fmt.Println("Performing setup...")
}
func main() {// 在第一次调用时执行 setup 函数once.Do(setup)// 在第二次调用时不执行任何操作once.Do(func() { fmt.Println("This shouldn't be printed.") })
}

在这个例子中,我们首先定义了一个 sync.Once 类型的变量 once。然后,我们使用 once.Do() 方法来指定要执行的操作。在第一次调用时,Do() 方法会执行 setup() 函数,输出 "Performing setup..."。在第二次调用时,Do() 方法不会执行任何操作,因为 setup() 函数已经被执行过了。

需要注意的是,Do() 方法是阻塞的,也就是说,在第一次调用还没有完成之前,后续的调用会被阻塞。这个特性可以用来保证只有一个 Goroutine 执行指定的操作,而其他 Goroutine 等待它完成之后再继续执行。此外,Do() 方法只会执行一次指定的操作,即使在多个 Goroutine 中调用它。这个特性可以用来避免重复初始化等问题。

17. 什么操作叫做原子操作?

在并发编程中,原子操作是一种不可中断的操作,要么全部完成,要么全部不完成。这意味着在多线程环境下,原子操作可以保证数据的一致性和可靠性,防止多个线程同时对同一数据进行操作而导致的竞争条件和数据不一致。

在 Go 语言中,sync/atomic 包提供了一些原子操作函数,用于在多线程环境中执行原子操作。这些原子操作函数可以确保对共享变量的访问是原子的,即不会被其他线程打断。

例如,atomic.AddInt64() 函数可以对一个 int64 类型的变量进行原子加法操作。以下是一个简单的示例:

package main
import ("fmt""sync/atomic"
)
func main() {var count int64// 对 count 变量进行 100 次原子加法操作for i := 0; i < 100; i++ {atomic.AddInt64(&count, 1)}fmt.Println("count:", count)
}

在这个例子中,我们首先定义了一个 int64 类型的变量 count,并使用 atomic.AddInt64() 函数对它进行 100 次原子加法操作。AddInt64() 函数的第一个参数是一个指向 int64 类型变量的指针,它告诉函数要对哪个变量进行原子操作。第二个参数是要添加的值。在这个例子中,我们每次添加的值都是 1。最后,我们输出 count 变量的值,应该是 100。

需要注意的是,原子操作函数仅保证对共享变量的访问是原子的,但并不能保证对多个变量之间的操作是原子的。如果需要对多个变量进行原子操作,可以使用互斥锁或其他同步机制来保证线程安全。

18. Go 原子操作有哪些?

Go atomic 包是最轻量级的锁(也称无锁结构),可以在不形成临界区和创建互斥量的情况下完成并发安全的值替换操作,不过这个包只支持 int32/int64/uint32/uint64/uintptr 这几种数据类型的一些基础操作(增减、交换、载入、存储等)。

概念:

原子操作仅会由一个独立的 CPU 指令代表和完成。原子操作是无锁的,常常直接通过 CPU 指令直接实现。 事实上,其它同步技术的实现常常依赖于原子操作。

使用场景:

当我们想要对某个变量并发安全的修改,除了使用官方提供的 mutex,还可以使用 sync/atomic 包的原子操作,它能够保证对变量的读取或修改期间不被其他的协程所影响。

atomic 包提供的原子操作能够确保任一时刻只有一个 goroutine 对变量进行操作,善用 atomic 能够避免程序中出现大量的锁操作。

常见操作:

  • 增减 Add

  • 载入 Load

  • 比较并交换 CompareAndSwap

  • 交换 Swap

  • 存储 Store

atomic 操作的对象是一个地址,你需要把可寻址的变量的地址作为参数传递给方法,而不是把变量的值传递给方法。下面将分别介绍这些操作:

增减操作

此类操作的前缀为 Add

func AddInt32(addr *int32, delta int32) (new int32)
func AddInt64(addr *int64, delta int64) (new int64)
func AddUint32(addr *uint32, delta uint32) (new uint32)
func AddUint64(addr *uint64, delta uint64) (new uint64)
func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)

需要注意的是,第一个参数必须是指针类型的值,通过指针变量可以获取被操作数在内存中的地址,从而施加特殊的 CPU 指令,确保同一时间只有一个 goroutine 能够进行操作。

使用举例:

func add(addr *int64, delta int64) {atomic.AddInt64(addr, delta) //加操作fmt.Println("add opts: ", *addr)
}

载入操作

此类操作的前缀为 Load

func LoadInt32(addr *int32) (val int32)
func LoadInt64(addr *int64) (val int64)
func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
func LoadUint32(addr *uint32) (val uint32)
func LoadUint64(addr *uint64) (val uint64)
func LoadUintptr(addr *uintptr) (val uintptr)
// 特殊类型: Value类型,常用于配置变更
func (v *Value) Load() (x interface{}) {}

载入操作能够保证原子的读变量的值,当读取的时候,任何其他 CPU 操作都无法对该变量进行读写,其实现机制受到底层硬件的支持。

使用示例:

func load(addr *int64) {fmt.Println("load opts: ", atomic.LoadInt64(&opts))
}

比较并交换

此类操作的前缀为 CompareAndSwap,该操作简称 CAS,可以用来实现乐观锁:

func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)
func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)

该操作在进行交换前首先确保变量的值未被更改,即仍然保持参数 old 所记录的值,满足此前提下才进行交换操作。CAS 的做法类似操作数据库时常见的乐观锁机制。

需要注意的是,当有大量的 goroutine 对变量进行读写操作时,可能导致 CAS 操作无法成功,这时可以利用 for 循环多次尝试。

使用示例:

func compareAndSwap(addr *int64, oldValue int64, newValue int64) {if atomic.CompareAndSwapInt64(addr, oldValue, newValue) {fmt.Println("cas opts: ", *addr)return}
}

交换

此类操作的前缀为 Swap

func SwapInt32(addr *int32, new int32) (old int32)
func SwapInt64(addr *int64, new int64) (old int64)
func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)
func SwapUint32(addr *uint32, new uint32) (old uint32)
func SwapUint64(addr *uint64, new uint64) (old uint64)
func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)

相对于 CAS,明显此类操作更为暴力直接,并不管变量的旧值是否被改变,直接赋予新值然后返回被替换的值。

func swap(addr *int64, newValue int64) {atomic.SwapInt64(addr, newValue)fmt.Println("swap opts: ", *addr)
}

存储

此类操作的前缀为 Store

func StoreInt32(addr *int32, val int32)
func StoreInt64(addr *int64, val int64)
func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)
func StoreUint32(addr *uint32, val uint32)
func StoreUint64(addr *uint64, val uint64)
func StoreUintptr(addr *uintptr, val uintptr)
// 特殊类型: Value类型,常用于配置变更
func (v *Value) Store(x interface{})

此类操作确保了写变量的原子性,避免其他操作读到了修改变量过程中的脏数据。

func store(addr *int64, newValue int64) {atomic.StoreInt64(addr, newValue)fmt.Println("store opts: ", *addr)
}

http://www.dinnco.com/news/35441.html

相关文章:

  • 黑河网站建设查权重
  • 通辽做家教的网站标题优化seo
  • 枣庄手机网站建设电话百度推广找谁做
  • 江苏省工程造价信息网镇江seo优化
  • 云鼎大数据888元建站网络营销策划是什么
  • 东莞三合一网站制作郑州网站建设推广
  • 0网站建设的好坏可以依据的标准有宁波网站建设优化企业
  • 会网站建设好吗网络营销的优势有哪些?
  • 深圳前十网站建设公司日本域名注册网站
  • 做app网站设计seo排名优化推广
  • 怎么做网站门户写一篇软文1000字
  • 上海企业网站建设价格网络推广有哪些常见的推广方法
  • 龙岗网站-建设深圳信科潍坊网站建设解决方案
  • 只有一个页面的网站怎么做安徽seo顾问服务
  • 织梦网站采集侠怎么做考研培训
  • 网站app定制促销策略的四种方式
  • wordpress是不是一定要买服务器网站seo优化8888
  • 软件开发需要哪些人员杭州seo优化
  • 做网站如何月入过万百度人气榜
  • 经营网站如何挣钱重庆百度总代理
  • 市政府投资建设项目管理中心网站如何注册域名
  • 外贸网站一站式海外推广企业网站营销的实现方式
  • 外贸网站哪家好网络营销的手段包括
  • 网站下拉菜单设计怎么自己制作网站
  • 淄博企业网站建设哪家好今天的新闻 最新消息
  • 交易网站前期建设方案北京seo顾问服务公司
  • 企业网站开发 文献综述dw网页设计模板网站
  • qq空间做淘宝客网站北京营销网站制作
  • 怎么让网站能被百度到专业的网站优化公司
  • 长春网站制作招聘信息seo交互论坛