zoukankan      html  css  js  c++  java
  • 将通道用做互斥锁(mutex)

    通道用例大全 - Go语言101(通俗版Go白皮书) https://gfw.go101.org/article/channel-use-cases.html

    将通道用做互斥锁(mutex)

    上面的某个例子提到了容量为1的缓冲通道可以用做一次性二元信号量。 事实上,容量为1的缓冲通道也可以用做多次性二元信号量(即互斥锁)尽管这样的互斥锁效率不如sync标准库包中提供的互斥锁高效。

    有两种方式将一个容量为1的缓冲通道用做互斥锁:
    1. 通过发送操作来加锁,通过接收操作来解锁;
    2. 通过接收操作来加锁,通过发送操作来解锁。

     

    下面是一个通过发送操作来加锁的例子。
    package main
    
    import "fmt"
    
    func main() {
    	mutex := make(chan struct{}, 1) // 容量必须为1
    
    	counter := 0
    	increase := func() {
    		mutex <- struct{}{} // 加锁
    		counter++
    		<-mutex // 解锁
    	}
    
    	increase1000 := func(done chan<- struct{}) {
    		for i := 0; i < 1000; i++ {
    			increase()
    		}
    		done <- struct{}{}
    	}
    
    	done := make(chan struct{})
    	go increase1000(done)
    	go increase1000(done)
    	<-done; <-done
    	fmt.Println(counter) // 2000
    }
    

     

    下面是一个通过接收操作来加锁的例子,其中只显示了相对于上例而修改了的部分。
    ...
    func main() {
    	mutex := make(chan struct{}, 1)
    	mutex <- struct{}{} // 此行是必需的
    
    	counter := 0
    	increase := func() {
    		<-mutex // 加锁
    		counter++
    		mutex <- struct{}{} // 解锁
    	}
    ...
    

     

    将通道用做互斥锁(mutex)

    上面的某个例子提到了容量为1的缓冲通道可以用做一次性二元信号量。 事实上,容量为1的缓冲通道也可以用做多次性二元信号量(即互斥锁)尽管这样的互斥锁效率不如sync标准库包中提供的互斥锁高效。

    有两种方式将一个容量为1的缓冲通道用做互斥锁:
    1. 通过发送操作来加锁,通过接收操作来解锁;
    2. 通过接收操作来加锁,通过发送操作来解锁。

     

    下面是一个通过发送操作来加锁的例子。
    package main
    
    import "fmt"
    
    func main() {
    	mutex := make(chan struct{}, 1) // 容量必须为1
    
    	counter := 0
    	increase := func() {
    		mutex <- struct{}{} // 加锁
    		counter++
    		<-mutex // 解锁
    	}
    
    	increase1000 := func(done chan<- struct{}) {
    		for i := 0; i < 1000; i++ {
    			increase()
    		}
    		done <- struct{}{}
    	}
    
    	done := make(chan struct{})
    	go increase1000(done)
    	go increase1000(done)
    	<-done; <-done
    	fmt.Println(counter) // 2000
    }
    

     

    下面是一个通过接收操作来加锁的例子,其中只显示了相对于上例而修改了的部分。
    ...
    func main() {
    	mutex := make(chan struct{}, 1)
    	mutex <- struct{}{} // 此行是必需的
    
    	counter := 0
    	increase := func() {
    		<-mutex // 加锁
    		counter++
    		mutex <- struct{}{} // 解锁
    	}
    ...
    

     

     

  • 相关阅读:
    【编程题目】输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。
    【编程题目】在一个字符串中找到第一个只出现一次的字符。如输入 abaccdeff,则输出 b。
    Unity3d 开发(七)AssetBundle组织文件夹
    MapReduce 的类型与格式【编写最简单的mapreduce】(1)
    Asterisk[1]
    1181: 念数字
    怎样創建 iOS 展開式 UITableView?
    android自己定义圆盘时钟
    iOS设计模式之NSNotificationCenter 消息中心
    大浪淘沙,JSP终将死去
  • 原文地址:https://www.cnblogs.com/rsapaper/p/15691190.html
Copyright © 2011-2022 走看看