首页 > 其他分享 >Go - Making Arrays and Slices Safe for Concurrent Use

Go - Making Arrays and Slices Safe for Concurrent Use

时间:2023-10-08 10:35:50浏览次数:39  
标签:Use Slices Arrays fmt Printf num mutex time shared

Problem: You want to make arrays and slices safe for concurrent use by multiple goroutines.


Solution: Use a mutex from the sync library to safeguard the array or slice. Lock the array or slice before modifying it, and unlock it after modifications are made.

 

Arrays and slices are not safe for concurrent use. If you are going to share a slice or array between goroutines, you need to make it safe from race conditions. Go provides a sync package that can be used for this, in particular, Mutex .

Race conditions occur when a shared resource is used by multiple goroutines trying to access it at the same time:

var   shared   [] int   =   [] int { 1 ,   2 ,   3 ,   4 ,   5 ,   6 } 

//  increase  each  element  by  1 
func   increase ( num   int )   { 
      fmt . Printf ( "[+%d  a]  :  %v\n" ,   num ,   shared ) 
      for   i   :=   0 ;   i   <   len ( shared );   i ++   { 
          time . Sleep ( 20   *   time . Microsecond ) 
          shared [ i ]   =   shared [ i ]   +   1 
      } 
      fmt . Printf ( "[+%d  b]  :  %v\n" ,   num ,   shared ) 
} 
 
//  decrease  each  element  by  1 
func   decrease ( num   int )   { 
      fmt . Printf ( "[ - %d  a]  :  %v\n" ,   num ,   shared ) 
      for   i   :=   0 ;   i   <   len ( shared );   i ++   { 
          time . Sleep ( 10   *   time . Microsecond ) 
          shared [ i ]   =   shared [ i ]   -   1 
      } 
      fmt . Printf ( "[ - %d  b]  :  %v\n" ,   num ,   shared ) 
}

 

func   main ()   { 
      for   i   :=   0 ;   i   <   5 ;   i ++   { 
          go   increase ( i ) 
      } 
      for   i   :=   0 ;   i   <   5 ;   i ++   { 
          go   decrease ( i ) 
      } 
      time . Sleep ( 2   *   time . Second ) 
}

When you run the program, you will see something like this:

[ - 4  a]  :  [1  2  3  4  5  6]
[ - 1  a]  :  [0  2  3  4  5  6]
[ - 2  a]  :  [0  1  3  4  5  6]
[ - 3  a]  :  [0  1  2  4  5  6]
[+0  a]  :  [ - 2  1  2  3  5  6]
[+1  a]  :  [ - 3  - 1  2  3  4  6]
[ - 4  b]  :  [ - 2  - 2  1  3  4  5]
[+3  a]  :  [ - 2  - 2  0  3  4  5]
[+4  a]  :  [ - 1  - 1  - 1  1  4  5]
[ - 1  b]  :  [1  0  0  0  1  4]
[ - 2  b]  :  [1  0  0  0  1  3]
[ - 3  b]  :  [1  0  0  0  1  2]
[+2  a]  :  [1  0  0  0  1  2]
[ - 0  a]  :  [2  2  1  1  1  2]
[+0  b]  :  [1  2  3  2  1  3]
[ - 0  b]  :  [1  2  3  3  2  2]
[+1  b]  :  [1  2  3  4  4  3]
[+3  b]  :  [1  2  3  4  4  4]
[+4  b]  :  [1  2  3  4  4  5]
[+2  b]  :  [1  2  3  4  5  6]

How can you prevent such race conditions? Go has the sync package in the standard library that provides you with a mutex , or a mutual exclusion lock:

 

var   shared   [] int   =   [] int { 1 ,   2 ,   3 ,   4 ,   5 ,   6 } 
var   mutex   sync . Mutex 
 
//  increase  each  element  by  1 
func   increaseWithMutex ( num   int )   { 
      mutex . Lock () 
      fmt . Printf ( "[+%d  a]  :  %v\n" ,   num ,   shared ) 
      for   i   :=   0 ;   i   <   len ( shared );   i ++   { 
          time . Sleep ( 20   *   time . Microsecond ) 
          shared [ i ]   =   shared [ i ]   +   1 
      } 
      fmt . Printf ( "[+%d  b]  :  %v\n" ,   num ,   shared ) 
      mutex . Unlock () 
} 

//  decrease  each  element  by  1 
func   decreaseWithMutex ( num   int )   { 
      mutex . Lock () 
      fmt . Printf ( "[ - %d  a]  :  %v\n" ,   num ,   shared ) 
      for   i   :=   0 ;   i   <   len ( shared );   i ++   { 
          time . Sleep ( 10   *   time . Microsecond ) 
          shared [ i ]   =   shared [ i ]   -   1 
      } 
      fmt . Printf ( "[ - %d  b]  :  %v\n" ,   num ,   shared ) 
      mutex . Unlock () 
} 

Using it is quite simple. First you need to declare a mutex. Then, you call Lock on the mutex before you start modifying the shared slice. This will lock the shared slice such that nothing else can use it. When you’re done, you call Unlock to unlock the mutex.

Here’s the output if you call these functions from main as before:

zzh@ZZHPC:/zdata/MyPrograms/Go/testing$ go run main.go
[ - 4 a] : [1 2 3 4 5 6]
[ - 4 b] : [0 1 2 3 4 5]
[+0 a] : [0 1 2 3 4 5]
[+0 b] : [1 2 3 4 5 6]
[+1 a] : [1 2 3 4 5 6]
[+1 b] : [2 3 4 5 6 7]
[+2 a] : [2 3 4 5 6 7]
[+2 b] : [3 4 5 6 7 8]
[+3 a] : [3 4 5 6 7 8]
[+3 b] : [4 5 6 7 8 9]
[+4 a] : [4 5 6 7 8 9]
[+4 b] : [5 6 7 8 9 10]
[ - 0 a] : [5 6 7 8 9 10]
[ - 0 b] : [4 5 6 7 8 9]
[ - 1 a] : [4 5 6 7 8 9]
[ - 1 b] : [3 4 5 6 7 8]
[ - 2 a] : [3 4 5 6 7 8]
[ - 2 b] : [2 3 4 5 6 7]
[ - 3 a] : [2 3 4 5 6 7]
[ - 3 b] : [1 2 3 4 5 6]
zzh@ZZHPC:/zdata/MyPrograms/Go/testing$ go run main.go
[+2 a] : [1 2 3 4 5 6]
[+2 b] : [2 3 4 5 6 7]
[+0 a] : [2 3 4 5 6 7]
[+0 b] : [3 4 5 6 7 8]
[ - 0 a] : [3 4 5 6 7 8]
[ - 0 b] : [2 3 4 5 6 7]
[+3 a] : [2 3 4 5 6 7]
[+3 b] : [3 4 5 6 7 8]
[ - 4 a] : [3 4 5 6 7 8]
[ - 4 b] : [2 3 4 5 6 7]
[ - 1 a] : [2 3 4 5 6 7]
[ - 1 b] : [1 2 3 4 5 6]
[ - 2 a] : [1 2 3 4 5 6]
[ - 2 b] : [0 1 2 3 4 5]
[+4 a] : [0 1 2 3 4 5]
[+4 b] : [1 2 3 4 5 6]
[ - 3 a] : [1 2 3 4 5 6]
[ - 3 b] : [0 1 2 3 4 5]
[+1 a] : [0 1 2 3 4 5]
[+1 b] : [1 2 3 4 5 6]

 

标签:Use,Slices,Arrays,fmt,Printf,num,mutex,time,shared
From: https://www.cnblogs.com/zhangzhihui/p/17748266.html

相关文章

  • slices in Go 1.21
    Go1.21中新增的slices包中提供了很多与切片相关的函数,适用于任意类型的切片。本文内容来自官方文档BinarySearch函数签名如下:funcBinarySearch[S~[]E,Ecmp.Ordered](xS,targetE)(int,bool)BinarySearch在已排序的切片中搜索target并返回找到target的位置,或......
  • CF1856B Good Arrays
    题意简述:给定一个序列\(a\),我们定义一个序列\(b\)是好的当且仅当对于\(1\dotsn\)内的每一个\(i\),\(a_i\neqb_i\)且\(\sum_{i=1}^na_i=\sum_{i=1}^nb_i\)(\(a_i\),\(b_i\)均为正整数)。现在有\(T\)组数据,每组数据给定\(n\)和序列\(a\),判断是否存在一个合法的序......
  • ClickHouse选择正确的join算法
    支持的JOIN类型 JOIN算法概览clickhouse提供了6种JOIN算法:1.直接连接(Directjoin)2.哈希连接(Hashjoin)3.并行哈希连接(Parallelhashjoin)4.优雅哈希连接(Gracehashjoin)5.全排序合并连接(Fullsortingmergejoin)6.部分合并连接(Partialmergejoin) 这......
  • 2023-10-06 useState数据渲染不同步==》async await
    业务:点击按钮增加数据并渲染出来。框架:antd+ts+react。原来写法:const[tagData,setTagData]=useState<Array<number>>([]);点击事件://添加标签constaddTag=()=>{letarr:(number)[]=[];arr=tagData;arr.push(Math.floor(Math.random()......
  • This generated password is for development use only. Your security configuration
    问题描述在我加上spring-boot-starter-security的依赖之后,启动项目报出来这样的错误:问题解决在启动类的注解上,加上这么一段代码就ok啦!启动成功:......
  • C++ namespace User_Unauthorized version 1.0.0 is officially released
    CodenamespaceUser_Unauthorized{/***@briefThisisaheaderfileforcompetitiveprogramming.*@authorUser-Unauthorized*@version1.0.0*@date2023-10-5*/typedeflonglongvalueType;typedefstd::vector<......
  • 火山引擎 ByteHouse:TB 级数据下,如何实现高效、稳定的数据导入
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群近期,火山引擎开发者社区、火山引擎数智平台(VeDI)联合举办以《数智化转型背景下的火山引擎大数据技术揭秘》为主题的线下Meeup。活动主要从数据分析、数据治理、研发提效等角度,带领数据领域从业者......
  • 火山引擎 ByteHouse 与白鲸开源完成兼容性认证,加速数据价值释放
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群数据作为新型生产要素,已快速融入生产、分配、流通、消费和社会服务管理等各环节,深刻改变着生产方式、生活方式和治理方式。越来越多企业也在尝试充分利用数据要素,开辟全新发展路径,进一步实现业务......
  • "Caused by: java.nio.file.AccessDeniedException: /usr/share/elasticsearch/data/n
    docker-compose搭建elasticsearch出现问题例子如下version:'3'services:elasticsearch:image:elasticsearch:7.14.0container_name:elasticsearchenvironment:-"discovery.type=single-node"-"xpack.sec......
  • 解决警告UserWarning: Glyph 38388 (\N{CJK UNIFIED IDEOGRAPH-95F4}) missing from
    这个警告是由于在绘图时使用了当前字体不支持的字符,通常出现在使用非英文字符(比如中文、日文等)时。为了解决这个问题,你可以尝试以下几种方法:方法一:选择支持中文的字体在绘图之前,指定一个支持中文的字体。例如,可以使用matplotlib.rcParams来指定字体,示例如下:importmatplotlib.pyplo......