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

网站建设的优势广告接单平台有哪些

网站建设的优势,广告接单平台有哪些,专业的团队网站建设,转 如何用java做网站Goroutine与并发编程的关系 什么是并发 是指多个任务在同一时间段内进行处理,但不一定是在同一时刻执行。并发强调的是“结构上的并行性”,也就是说,程序能够在一个时间端内同时处理多个任务,但是这些任务可能是交替进行的。例如…

Goroutine与并发编程的关系

什么是并发

是指多个任务在同一时间段内进行处理,但不一定是在同一时刻执行。并发强调的是“结构上的并行性”,也就是说,程序能够在一个时间端内同时处理多个任务,但是这些任务可能是交替进行的。例如:一个cpu可以迅速切换任务的上下文,给人一种多个任务在“并行”执行的感觉。

并发的主要特点是能够处理多个任务,而这些任务并不需要同时执行,但在某种情况下它们可以并行执行。并发的关键在于如何有效的切换任务和处理共享资源。

并发的核心就是让多个任务有机会被处理,而不需要等待其他任务完全结束。

goroutine与并发的关系

在Go语言中,goruoutine是并发的基本单位,它是一种轻量级的线程,由Go运行时管理。与传统的线程相比,goroutine占用的资源非常小,因此在程序中启动成千上万个goroutine,不会造成过高的开销。

goroutine通过Go的调度器进行管理,调度器负责讲goroutine映射到操作系统的线程上。goroutine在并发模型中的作用是允许程序处理多个任务,它的本质是轻量级的“线程”,但由于Go提供了对goroutine的高效调度,goroutine的使用非常灵活和高效。

goroutine 如何实现并发?
  • 轻量级任务:goroutine 被设计为非常轻量级的任务。启动一个 goroutine 需要的内存比传统线程要少很多,因此你可以并发执行成千上万的 goroutine。
  • 自动调度:Go 运行时内置的调度器会自动将 goroutine 映射到 CPU 上的可用线程上,从而实现并发执行。Go 程序不需要手动管理线程池或调度机制。
  • 非阻塞执行:在执行 goroutine 时,即使某个 goroutine 因为 I/O 操作或其他原因阻塞了,Go 的调度器仍然可以将其他 goroutine 调度到 CPU 上继续执行,从而保持并发运行。

Go语言中的锁

互斥锁,读写锁

锁的思想:乐观锁,悲观锁

互斥锁()

1.1定义

互斥锁是一个用于保护临界区的同步用语,它的所用是确保统一时刻只有一个goroutine能访问被保护的共享资源。通过互斥锁,可以避免并发访问带来的数据竞争问题。

1.2示例代码:

package mainimport ("fmt""sync"
)var (mutex sync.Mutexcount int
)func increment() {mutex.Lock()   // 获取锁count++mutex.Unlock() // 释放锁
}func main() {var wg sync.WaitGroup// 启动多个 goroutine 并发执行for i := 0; i < 10; i++ {wg.Add(1)go func() {defer wg.Done()increment()}()}wg.Wait() // 等待所有 goroutine 完成fmt.Println("Final count:", count)
}

在这个示例中,mutex 被用来确保同一时刻只有一个 goroutine 能够访问 count 变量。由于有多个 goroutine 在并发地执行 increment 函数,通过 mutex.Lock()mutex.Unlock() 确保了线程安全。

1.3注意事项

  • 死锁:如果一个 goroutine 在持有锁时没有及时释放锁,或者两个 goroutine 相互等待对方释放锁,可能会导致死锁。为了避免死锁,确保每个 Lock() 都有对应的 Unlock(),并且尽量减少锁持有的时间。
  • 锁的嵌套:避免在持有锁时再次请求锁,除非非常必要,否则会增加死锁的风险。

读写锁

2.1 定义与原理

读写锁(RWMutex)是为了优化读操作频繁的场景设计的锁。与互斥锁不同,读写锁允许多个 goroutine 同时进行读操作,但写操作是互斥的,只有在没有任何读操作或写操作进行时,才能进行写操作。

  • RLock():用于加读锁,多个 goroutine 可以同时持有读锁,只要没有其他 goroutine 持有写锁。
  • RUnlock():释放读锁。
  • Lock():用于加写锁,写锁是独占的,只有一个 goroutine 可以持有写锁。
  • Unlock():释放写锁。

2.2 使用示例

package mainimport ("fmt""sync"
)var (rwMutex sync.RWMutexdata    int
)func read() {rwMutex.RLock()  // 获取读锁defer rwMutex.RUnlock()fmt.Println("Reading data:", data)
}func write(value int) {rwMutex.Lock()   // 获取写锁defer rwMutex.Unlock()data = valuefmt.Println("Writing data:", value)
}func main() {var wg sync.WaitGroup// 启动多个 goroutine 执行读操作for i := 0; i < 5; i++ {wg.Add(1)go func() {defer wg.Done()read()}()}// 启动一个 goroutine 执行写操作wg.Add(1)go func() {defer wg.Done()write(42)}()wg.Wait()
}

在这个示例中,read 函数通过 rwMutex.RLock() 获取读锁,允许多个 goroutine 同时执行读取操作。而 write 函数则通过 rwMutex.Lock() 获取写锁,保证写操作是独占的,不会与读操作同时进行。

2.3 适用场景

  • 读多写少:读写锁特别适合读多写少的场景。当读操作远远多于写操作时,使用读写锁可以显著提高性能,因为多个读操作可以并发执行,而不必等待锁的释放。
  • 写操作必须独占:写操作会阻塞所有读操作和其他写操作,确保写操作的安全性。

2.4 与互斥锁的区别

  • 互斥锁是严格的互斥机制,即同一时刻只能有一个 goroutine 执行临界区代码(无论是读还是写)。
  • 读写锁允许多个 goroutine 同时读共享资源,但在写共享资源时,写操作需要独占资源。

当程序中存在大量读操作时,读写锁可以提供更高的并发性,因为它允许多个读操作同时进行,而不会像互斥锁那样相互阻塞。

3. 何时使用互斥锁,何时使用读写锁?

  • 使用互斥锁
    • 如果操作是读写混合的,或者读写的比例相当,使用互斥锁会更简单直接。
    • 如果共享资源的访问量很小,读写锁可能带来的复杂性不值得使用。
  • 使用读写锁
    • 如果你的应用场景下,读操作远多于写操作,使用读写锁可以提高性能,允许多个 goroutine 并发读数据,同时保证写操作的独占性。
    • 读写锁比互斥锁更复杂,因此如果读写比不明显,使用互斥锁可能更为简单 

两种锁的思想:悲观锁和乐观锁 

悲观锁

2.1 定义与原理

悲观锁的核心思想是假设并发操作会引发冲突,因此在访问共享资源时,采用加锁的方式防止其他 goroutine 同时访问该资源。只有在获取锁之后,才能对共享资源进行操作,其他 goroutine 必须等待锁被释放。

  • 特点:总是先加锁,再访问资源,保证在同一时刻只有一个 goroutine 能够访问资源。
  • 锁的粒度:锁的粒度较大(例如,一次获取整个资源的锁),因此会影响系统的并发性能。

在 Go 中,sync.Mutexsync.RWMutex 就是典型的悲观锁实现:

  • sync.Mutex:互斥锁,整个资源加锁,防止其他 goroutine 访问。
  • sync.RWMutex:读写锁,写操作是互斥的,而读操作可以并发执行,但在写操作时,所有读操作和其他写操作会被阻塞。

2.2 示例

假设我们有一个共享变量,需要通过悲观锁来保护:

package mainimport ("fmt""sync"
)var (mutex sync.Mutexcount int
)func increment() {mutex.Lock()   // 获取锁defer mutex.Unlock()count++
}func main() {var wg sync.WaitGroupfor i := 0; i < 10; i++ {wg.Add(1)go func() {defer wg.Done()increment()}()}wg.Wait()fmt.Println("Final count:", count)
}

在这个示例中,mutex.Lock()mutex.Unlock() 确保了只有一个 goroutine 能访问 count 变量,这就是一种典型的悲观锁机制。

2.3 使用场景

悲观锁通常用于以下场景:

  • 资源竞争严重:当多个 goroutine 频繁争抢资源时,悲观锁能确保对资源的访问是互斥的,避免并发问题。
  • 数据一致性要求高:当你无法接受并发操作对数据产生不一致时,使用悲观锁可以避免这类问题。

然而,悲观锁可能导致性能瓶颈,因为锁住了共享资源的访问,其他 goroutine 必须等待锁释放,导致并发性降低。

乐观锁

3.1 定义与原理

与悲观锁相对,乐观锁的核心思想是假设并发操作不会引发冲突,因此它不主动加锁,而是乐观地认为不会有并发冲突。在操作共享资源之前,乐观锁并不会加锁,而是在操作后检测是否发生了冲突。如果冲突发生,则回滚操作,重试或者放弃。

乐观锁通常通过一些“版本控制”机制来实现,例如通过“版本号”或者“时间戳”来判断数据是否发生变化。

  • 特点:乐观锁不会阻塞其他 goroutine,只有在数据写入时才检测冲突。通常适用于读多写少的场景。
  • 回滚重试机制:如果在提交操作时发现冲突,乐观锁通常会选择回滚并重试。

3.2 示例

Go 本身并没有直接实现乐观锁,但你可以通过一些简单的机制来模拟乐观锁。一个常见的方法是通过版本号(或时间戳)来判断资源是否被修改。

package mainimport ("fmt""sync"
)type Counter struct {value intversion int // 版本号,用于乐观锁mu sync.Mutex
}func (c *Counter) increment() bool {c.mu.Lock()defer c.mu.Unlock()// 记录当前版本号currentVersion := c.version// 执行增量操作c.value++// 模拟乐观锁:如果版本号没有变化,认为没有并发冲突if c.version == currentVersion {c.version++return true // 操作成功}// 如果版本号发生变化,表示有其他操作修改了数据,返回失败return false
}func main() {var wg sync.WaitGroupcounter := &Counter{}for i := 0; i < 10; i++ {wg.Add(1)go func() {defer wg.Done()// 模拟乐观锁重试for !counter.increment() {fmt.Println("Retrying...")}}()}wg.Wait()fmt.Println("Final count:", counter.value)
}

3.3 使用场景

乐观锁适用于以下场景:

  • 读操作远多于写操作:在大多数情况下,数据不会发生冲突,乐观锁能够减少不必要的加锁,提高性能。
  • 冲突发生概率低:如果你知道并发冲突发生的概率非常低,使用乐观锁可以提高效率。
  • 需要高并发读操作:乐观锁不需要加锁,允许多个 goroutine 同时读取数据,适用于高并发读场景。

然而,乐观锁的缺点在于需要处理冲突时的回滚和重试,尤其是在高并发写操作的场景中,重试的开销可能非常大。

乐观锁与悲观锁的对比

特性悲观锁乐观锁
假设假设并发冲突会发生,采取措施避免冲突假设并发冲突不会发生,事后检查冲突
加锁方式总是加锁,互斥访问不加锁,事后检查冲突
性能可能影响并发性能,锁竞争时会阻塞高并发读取时性能较好,但有回滚重试开销
适用场景资源竞争严重,数据一致性要求高读多写少,冲突概率低的场景

总结

  • 悲观锁:通过加锁保证数据一致性,适用于资源竞争严重的场景,但会影响系统的并发性能。
  • 乐观锁:假设没有冲突,允许多个 goroutine 并发访问资源,适用于读多写少、冲突概率低的场景,通常需要进行冲突检测和回滚。

在 Go 语言中,虽然我们大多数情况下使用的是悲观锁(例如 sync.Mutexsync.RWMutex),但在某些场景下,理解并应用乐观锁的思想可以帮助我们提升并发性能,尤其是在读操作远多于写操作的情况下。

http://www.tj-hxxt.cn/news/14152.html

相关文章:

  • 成都定制网站设云南疫情最新消息
  • 网站迁移后 域名网站seo软件
  • 建网站外包怎样推广自己的店铺啊
  • 营销团队外包南阳网站优化公司
  • 试列出网站开发建设的步骤互联网营销师培训教程
  • 国际新闻最新消息今天新闻大哪些行业适合做seo
  • 做网站流程seo排名技巧
  • 哪家可以做网站环球资源网官方网站
  • 潍坊市做网站的公司怎么自己制作一个网站
  • 常州北京网站建设网络营销名词解释答案
  • 扁平化 网站 模板技能培训网
  • 怎么做自己的电影网站美国seo薪酬
  • dede视频网站源码肇庆百度快照优化
  • 淮安哪里有做网站的网站你应该明白我的意思吗
  • 沙田镇网站建设公司黄页网
  • 网站搭建软件工具百度引擎搜索
  • 留言的网页怎么制作青岛seo搜索优化
  • 珠宝出售网站模板超级搜索引擎
  • 网站 三合一百度登录入口百度
  • 网站禁止火车头采集中文搜索引擎排名
  • 哪个网站做室内效果图厉害运营推广计划
  • 南宁网站建设公司网站seo分析工具
  • 做生鲜食品最好的网站网络营销策划需要包括哪些内容
  • 网站有中文源码加英文怎么做免费模板网站
  • 网站开发用软件廊坊百度seo公司
  • 文登住房与建设局网站网站维护中
  • 什么网站可以做简历大庆建站公司
  • 做软件去哪个网站谷歌搜索引擎
  • 网站咋做什么是搜索引擎营销?
  • 移动互联网项目创业融资计划书seo渠道是什么意思