为了账号安全,请及时绑定邮箱和手机立即绑定

如何对多个 goroutine 共享的数据结构执行并发操作

如何对多个 goroutine 共享的数据结构执行并发操作

Go
慕田峪7331174 2022-11-08 16:55:48
我在 Go 中解决了一个难题,它通过旋转 ASCII 字节值以匹配行方式(左->右)或列方式(顶部->底部)的字符串,在 2D 字节数组中找到一个字符串。我能够按顺序解决它,当它同时解决它时,我尝试启动一个 go-routine 来处理特定的输入组合,看看是否有任何可能的 25 个旋转可以找到匹配项。代码摘要如下该FindByConcurrentRot方法采用 2D 字符数组输入并尝试在各种可能的输入组合中找到字符串的匹配项。问题是 - 下面使用的并发方法是否有效?如何改进?将顺序例程“按原样”转换为并发程序的方法是否错误?即是否应该重写整个程序以充分利用并发特性?// searchResult defines the information needed to pass to identify if a match has been identified during concurrent searchtype searchResult struct {    row   int    col   int    rot   int    found bool}// processSearchResults runs the gorotuine to perform the search for a particular rotation of inputfunc processSearchResults(wg *sync.WaitGroup, iter int, resultChan chan searchResult, table [][]byte, word string) {    // call goroutine end when the function returns    defer wg.Done()    if iter >= 1 {        rotate(table, iter)    }    x, y, match := present(table, word)    if match {        resultChan <- searchResult{row: x, col: y, rot: iter, found: true}        return    }    resultChan <- searchResult{found: false}}// doCopy creates a copy of the original table to passed for each iteration of the concurrent search// This is an EXPENSIVE operation on a goroutine, because of memory copy operations// The copy is needed for the goroutines to have their own control of data and not run into data// races by passing the original data to each of themfunc doCopy(table [][]byte) [][]byte {    copyTable := make([][]byte, len(table))    for i := range table {        copyTable[i] = make([]byte, len(table[i]))        copy(copyTable[i], table[i])    }    return copyTable}此 Go 操场链接上的完整 MVCE - https://go.dev/play/p/7YFAsAlFRUw
查看完整描述

1 回答

?
慕码人2483693

TA贡献1860条经验 获得超9个赞

这种方法很可能会因复制表所花费的周期过多而受到影响。由于每个 goroutine 都在修改表,因此每个 goroutine 都必须获得一个单独的副本。


另一种方法是在只读表的顶部添加一个层,为每个 goroutine 提供修改后的视图。这并不能保证更好的性能,但它可能比使用多个 goroutine 复制的性能更好。


方法是有一个表格视图:


type tableView struct {

   inc int

   table [][]byte

}


func (t tableView) get(row,col int) byte {

   v:=t.table[row][col]

   v+=t.inc

   if v>'z' {...}

   return v

}

然后,您初始化并传递一个 tableView 实例。


再说一遍:这可能不会像您期望的那样快,但它可能比表的多个副本执行得更好。您必须测试并查看。


查看完整回答
反对 回复 2022-11-08
  • 1 回答
  • 0 关注
  • 110 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号