美文网首页
多线程读写共享变量的几种处理模式

多线程读写共享变量的几种处理模式

作者: lesliefang | 来源:发表于2017-12-02 15:27 被阅读283次

将共享变量的读写放到一个 goroutine 中,其它 goroutine 通过 channel 进行读写操作,这种方式有很多好处。

package bank

var deposits = make(chan int) // send amout to deposit
var balances = make(chan int) // receive balance

func Deposit(amount int) {
    deposits <- amount
}

func Balance() int {
    return <-balances
}

func teller() {
    var balance int // balance 只在 teller 中可以访问
    for {
        select {
        case amount := <-deposits:
            balance += amount
        case balances <- balance:
        }
    }
}

func init() {
    go teller()
}

第二种就是最常见的互斥了,共享变量要互斥访问
可以用个数为 1 的信号量(semaphore)实现互斥

var (
    sema    = make(chan struct{}, 1)
    balance int
)

func Deposit(amout int) {
    sema <- struct{}{} // acquire token
    balance = balance + amout
    <-sema // release token
}

func Balance() int {
    sema <- struct{}{} // acquire token
    b := balance
    <-sema // release token
    return b
}

go 内部提供了互斥操作

import "sync"

var (
    mu      sync.Mutex
    balance int
)

func Deposit(amount int) {
    mu.Lock()
    defer mu.Unlock()
    balance = balance + amount
}

func Balance() int {
    mu.Lock()
    defer mu.Unlock()
    return balance
}

为什么 Balance 也需要互斥,多线程同时读取一个变量有问题吗??? Balance 也需要互斥是为了防止在写的过程中进行读取。如果在读的过程中没有线程在写多线程同时读取是没有问题的。所以为了提高读取的并发量可以用读写锁改写

var mu sync.RWMutex
var balance int
 func Balance() int {
     mu.RLock() // readers lock
     defer mu.RUnlock()
     return balance
}

Deposit 不变,Balance 只获取 RLock 读锁,只要没有线程在写,多个线程可同时获得 RLock 锁。

Do not communicate by sharing memory. Instead, share memory by communicating.

sync 库和 channel 的选择要看场景,哪种更简单更适合就用哪种。大部分场景可用 channel 实现。

相关文章

  • 多线程读写共享变量的几种处理模式

    将共享变量的读写放到一个 goroutine 中,其它 goroutine 通过 channel 进行读写操作,这...

  • 线程

    语法 多线程工作在单进程下。在多线程模式下,数据变量是被所有线程共享的。 1.创建线程 当两个处理函数同时操作一个...

  • Immutability模式

    多线程同时读写一共享变量存在并发问题,这里的必要条件之一是读写,如果只有读,而没有写,是没有并发问题的。 解决并发...

  • Volatile的内存语义

    内存语义 内存语义指的是:在多线程或处理器中用来控制存取共享内存位置,或者说是在更高层次上共享变量的处理逻辑。 v...

  • JAVA

    1.4 Java的 内存模型 是否线程安全线程安全与cpu资源的抢夺 多线程在读写共享变量时引发的问题 线程的原子...

  • 内存模型

    1.4 Java的 内存模型 是否线程安全线程安全与cpu资源的抢夺多线程在读写共享变量时引发的问题 线程的原子性...

  • 多线程

    打印正在运行的多个线程 通过继承的方式实现线程 多线程共享全局变量 多线程共享全局变量 args参数 互斥锁 如果...

  • ReadWriteLock读写锁

    读写锁,分场景优化,提升性能。 读写锁遵守的基本原则: 允许多个线程同时读共享变量。 只允许一个线程写共享变量。 ...

  • 第二章 Java并发机制的底层实现原理

    多线程中 volatile 是轻量级的 synchronized,他们在多处理器开发中保证了共享变量的可见性。可见...

  • Python多任务_线程

    简单使用 多线程共享全局变量-互斥锁

网友评论

      本文标题:多线程读写共享变量的几种处理模式

      本文链接:https://www.haomeiwen.com/subject/wgynbxtx.html