golang线程安全1-9

1.golang的map是线程安全的吗?怎么安全使用map

不安全,需要进行资源保护。
sync互斥锁,或者redis分布式锁

或者:这个字典类型提供了一些常用的键值存取操作方法,并保证了这些操作的并发安全
var ma sync.Map //该类型是开箱即用,只需要声明既可
ma.Store("key", "value") // 存储值
ma.Delete("key") //删除值
ma.LoadOrStore("key", "value")// 获取值,如果没有则存储
fmt.Println(ma.Load("key"))//获取值

//遍历
ma.Range(func(key, value interface{}) bool {
  fmt.Printf("key:%s ,value:%s \n", key, value)
  //如果返回:false,则退出循环,
  return true
})


合理使用go语言提供的标准库就可以写出高效率的代码,map

sync.map
1.sync.map的核心实现是两个map,一个用于写(加锁),一个用于读(无锁),这样设计的思想好比缓存与数据库
2.sync.map的局限性,如果写高于读(写加锁,刷数据到read都需要耗费资源),dirty>read,刷新数据的频率比较高,性能急剧下降。此时不如直接改造标准库map,rwmutex+map组合。
3.sync.map的设计思想--保证高频的读无锁,两个map。空间换时间

设计无锁的map

1.考虑用队列,channel
2.用乐观锁,多线程从map取值无所谓,修改map的值时用乐观锁。判断修改前后数据是否被改了,如果已经被改过则重新执行食物

2.进程,线程,协程共享什么,独享什么


进程、线程和协程是计算机中用于实现并发执行的三个重要概念。它们之间的共享和独享可以描述如下:

进程(Process):

共享:进程之间拥有独立的内存空间,因此彼此之间的数据是相互独立的,不共享数据。
独享:每个进程拥有独立的执行环境,包括代码、数据、文件描述符等,它们是相互独立的。
线程(Thread):

共享:线程属于同一个进程,它们共享进程的内存空间,可以直接访问相同的变量和数据结构。
独享:每个线程有自己的栈空间,用于保存线程的局部变量,线程之间的栈是独立的。
协程(Coroutine):

共享:协程是一种轻量级的线程,多个协程可以运行在同一个线程中。它们共享线程的上下文,包括变量、文件描述符等。
独享:每个协程都有自己的执行流程和局部变量,协程之间的执行是相互独立的。
总结:

进程拥有独立的内存空间和执行环境,数据不共享,执行环境独享。
线程共享进程的内存空间,可以直接访问相同的变量和数据结构,但每个线程有自己的栈空间。
协程共享线程的上下文,包括变量和文件描述符,但每个协程有自己的执行流程和局部变量。

3.进程状态转换

img

4.Log包线程安全吗?

安全,因为:
在输出的位置做了线程安全的保护,加了锁
l.mu.Lock()
defer l.mu.Unlock()

5.写的循环队列是不是线程安全?

channel上面实现的是线程安全

如果是切片实现,需要加锁实现线程安全。但是效率变低了
不是,怎么保证线程安全,加锁,效率有点低啊,Go推崇原子操作和channel

6.go协程线程安全吗

不安全,需要进行资源保护。
sync互斥锁,或者redis分布式锁

7.go为什么高并发好?go的调度模型

因为协程,go天生支持并发

GMP:
goroutine说到底其实就是协程,但是它比线程更小,几十个goroutine可能体现在底层就是五六个线程,Go语言内部帮你实现了这些goroutine之间的内存共享

8.Golang 中常用的并发模型

通过channel通知实现并发控制
通过sync包中的WaitGroup实现并发控制
在Go 1.7 以后引进的强大的Context上下文,实现并发控制

9.进程与线程

进程:资源单位(数据隔离)
线程:执行单位(数据共享)
​ ps:每个进程都自带一个线程,线程才是真正的执行单位,进程只是再线程中提供资源
posted @ 2022-03-03 14:38  Jeff的技术栈  阅读(268)  评论(0编辑  收藏  举报
回顶部