科学健康资讯 · 内容仅供参考,不替代专业诊疗 联系我们|疾病百科
操作系统

mutex_lock

2023-06-06 操作系统 本文链接

通常可以使用锁、信号量(Semaphores)、屏障(Barrier)和条件变量(Condition Variable)机制来实现线程同步。根据不同的并发场景分为很多不同类型的锁,有互斥锁(Mutex)、读写锁(RwLock)和自旋锁(Spinlock)等。锁的作用是可以保护临界区,同时达到同步和互斥的效果。不同的锁表现不同,比如互斥锁,每次只允许单个线程访问临界资源;读写锁可以同时支持多个线程读或单个线程写;自旋锁和互斥锁类似,但当获取锁失败时,它不会让线程睡眠,而是不断地轮询直到获取锁成功。

信号量可以在线程间传递信号,也叫作信号灯,它可以为资源访问进行计数。信号量是一个非负整数,所有通过它的线程都会将该整数减 1,如果信号量为 0,那么其他线程只能等待。当线程执行完毕离开临界区时,信号量会再次加1。当信号量只允许设置0和1时,效果相当于互斥锁。

屏障可以让一系列线程在某个指定的点进行同步。通过让参与指定屏障区域的线程等待,直到所有参与线程都到达指定的点。而条件变量用来自动阻塞一个线程,直到出现指定的条件,通常和互斥锁配合使用。通过一些锁机制,比如互斥锁,也可以用来避免数据竞争。本质上,是通过锁来保护指定区域的原子性的。有些语言也提供了原子类型来保证原子性,比如Java、C++以及Rust。具有原子性的操作一定是不可分割的,要么全部完成,要么什么都不做。

[go] 解决:concurrent write to websocket connection

出现这个问题是因为并发的调用了网页链接库的WriteMessage方法

在websocket连接上有多个groutinue同时调用写方法

go官方的解释:

并发

连接支持一个并发读取器和一个并发写入器。

应用程序负责确保不超过一个 goroutine 同时调用写入方法(NextWriter、SetWriteDeadline、WriteMessage、WriteJSON、EnableWriteCompression、SetCompressionLevel),并且不超过一个 goroutine 调用读取方法(NextReader、SetReadDeadline、ReadMessage、ReadJSON、SetPongHandler) , SetPingHandler) 并发。

Close 和 WriteControl 方法可以与所有其他方法可以并发调用。

每一个请求都是一个groutine,如果有多个groutine同时请求并且要写回数据,就会出现这个错误

一定要加上锁,并且在业务上避免多个同时调用

为了解决这一问题,我定义了一个全局的读写互斥锁(sync.RWMutex) 。

var WSWriteMux sync.RWMutex

在所有开始调用WriteMessage方法之前,先上锁。

调用完WriteMessage方法之后,再解锁。

WSWriteMux.Lock()

singlemap.wsconn.WriteMessage(websocket.TextMessage, []byte(base64.StdEncoding.EncodeToString([]byte(nmsg))))

WSWriteMux.Unlock()

本文内容仅供健康科普参考,不能替代专业医疗诊断和治疗建议。如有身体不适,请及时就医并遵从医师指导。

相关阅读