首页 > 其他分享 >使用fx.Parallel方法并发执行函数时遇到的惰性计算的坑

使用fx.Parallel方法并发执行函数时遇到的惰性计算的坑

时间:2023-05-27 12:44:38浏览次数:32  
标签:fns string fx lock allFriends 惰性 func Parallel append

错误的写法

package scripts_stroage

import (
    "encoding/hex"
    "fmt"
    "github.com/zeromicro/go-zero/core/fx"
    "math/rand"
    "sync"
    "testing"
    "time"
)

var fns []func()
var lock sync.Mutex
var allFriends []string

type student struct {
    Name    string
    Age     int
    Friends []string
}

func init() {
    rand.Seed(time.Now().UnixNano())
}

func RandStr2(n int) string {
    result := make([]byte, n/2)
    rand.Read(result)
    return hex.EncodeToString(result)
}

func genStudents() []student {
    ret := make([]student, 0)

    for i := 1; i < 5; i++ {
        currStu := student{
            Name:    fmt.Sprintf("whw_%v", i),
            Age:     i + 10,
            Friends: []string{RandStr2(3), RandStr2(4)},
        }
        ret = append(ret, currStu)
    }

    return ret
}

func TestT11T(t *testing.T) {

    stus := genStudents()
    fmt.Println(stus)

    // 注意:这里有 "惰性计算" 的坑
    for _, stu := range stus {
        if stu.Age > 13 {
            fns = append(fns, func() {
                lock.Lock()
                defer lock.Unlock()
                allFriends = append(allFriends, stu.Friends[0])
            })
        } else {
            fns = append(fns, func() {
                lock.Lock()
                defer lock.Unlock()
                allFriends = append(allFriends, stu.Friends...)
            })
        }
    }

    // 并发去执行 fns 中的函数
    fx.Parallel(fns...)

    fmt.Println("allFriends: ", allFriends)
    // 惰性计算的结果
    // [{whw_1 11 [a5 f487]} {whw_2 12 [66 1c7f]} {whw_3 13 [56 88b3]} {whw_4 14 [04 d505]}]
    // allFriends:  [04 04 d505 04 d505 04 d505]
}
有惰性计算的问题

避免惰性计算的写法

package scripts_stroage

import (
    "encoding/hex"
    "fmt"
    "github.com/zeromicro/go-zero/core/fx"
    "math/rand"
    "sync"
    "testing"
    "time"
)

var fns []func()
var lock sync.Mutex
var allFriends []string

type student struct {
    Name    string
    Age     int
    Friends []string
}

func init() {
    rand.Seed(time.Now().UnixNano())
}

func RandStr2(n int) string {
    result := make([]byte, n/2)
    rand.Read(result)
    return hex.EncodeToString(result)
}

func genStudents() []student {
    ret := make([]student, 0)

    for i := 1; i < 5; i++ {
        currStu := student{
            Name:    fmt.Sprintf("whw_%v", i),
            Age:     i + 10,
            Friends: []string{RandStr2(3), RandStr2(4)},
        }
        ret = append(ret, currStu)
    }

    return ret
}

func TestT11T(t *testing.T) {

    stus := genStudents()
    fmt.Println(stus)
    
    for _, stu := range stus {
        // 避免惰性计算:这里用临时变量去接收~
        currStu := stu
        if currStu.Age > 13 {
            fns = append(fns, func() {
                lock.Lock()
                defer lock.Unlock()
                allFriends = append(allFriends, currStu.Friends[0])
            })
        } else {
            fns = append(fns, func() {
                lock.Lock()
                defer lock.Unlock()
                allFriends = append(allFriends, currStu.Friends...)
            })
        }
    }

    // 并发去执行 fns 中的函数
    fx.Parallel(fns...)

    fmt.Println("allFriends: ", allFriends)
    // 正确的结果
    // [{whw_1 11 [37 41f0]} {whw_2 12 [cf 4895]} {whw_3 13 [d2 773b]} {whw_4 14 [e0 9ebd]}]
    // allFriends:  [e0 37 41f0 cf 4895 d2 773b]
}

~~~

标签:fns,string,fx,lock,allFriends,惰性,func,Parallel,append
From: https://www.cnblogs.com/paulwhw/p/17436567.html

相关文章

  • Flex实践——Parallel Practice
        前几次在学习Flex中的一些基本控件的使用,还顺便学了一小点ActionScript的应用,今天要学些What?来看看一些组合效果的应用吧,下面的实践将简单介绍把渐变和移动两种效果同时运用在一个组件上。    ( 引:Flex提供将超过一种的多种效果组合起来的能力。你可以使用<mx:P......
  • FX110网:全球主要机构货币交易量于4月下滑
    全球主要机构平台2023年4月份的交易量已经公布,呈现出整体下滑的趋势。报告涵盖了六个主要场所的机构货币交易量的日均交易量(ADV),即CboeFX、CLS、EuronextFX、FxSpotStream、Refinitiv、360T,如下图所示。这六家公司2023年4月的日均货币交易量与上月相比都有所下降。总体而言,Cboe的......
  • GitlabCI学习笔记之三:GitLabRunner pipeline语法之tags allow_faillure when retry ti
    1.tags用于从允许运行该项目的所有Runner列表中选择特定的Runner,在Runner注册期间,您可以指定Runner的标签。tags可让您使用指定了标签的runner来运行作业,此runner具有ruby和postgres标签。示例给定带有osx标签的OSXRunner和带有windows标签的WindowsRunner,以下作业将在......
  • FX110网:西班牙CNMV警告这6家交易商没有监管授权
    2023年5月22日,西班牙金融监管机构CNMV对6家未经授权的外汇交易商发出警告。根据《证券市场法》第17条第二款(由10月23日第4/2015号皇家法令批准的重订文本),西班牙国家证券市场委员会(ComisiónNacionaldelMercadodeValores)警告,以下公司未获授权提供《西班牙证券市场法》第140......
  • Parallel Query 导致的ORA-04031
    一个朋友遇到ORA-04031问题。虽然这个错误是非常常见的,然而这里的Case也有点让人为之震惊!TueAug2611:51:132014Errorsinfile/oracle/app/oracle/diag/rdbms/xx/xx1/trace/xx1_p485_28873.trc(incident=1589637)ORA-04031:无法分配32792字节的共享内存("sharedpoo......
  • FX110曝光:Royal Q APP虚拟骗局
    近期,一位马来西亚汇友爆料称其被引诱在RoyalQAPP加入了投资项目,结果怎么也出不了金。三番两次,盈利却取不出来据汇友描述,他发现自己无意间被一匿名者邀请加入了一个名为“RoyalQTrade”的电报群。在群组里,每天都有很多人晒出大量的盈利截图,晒出来的数据很是刺激眼球。看得多了......
  • oralce参数(块跟踪,parallel,附加日志)
    Oracle部分参数接触记录块跟踪问题背景:一个业务大库进行迁移后,数据库增量备份变得异常缓慢,甚至一天无法完成,影响业务安全性,提出开启块跟踪加快增备。开启(如需手动指定,rac需要在asm存储,文件系统可设置为本地)alterdatabaseenableblockchangetrackingusingfile'+DATA';或alt......
  • 通过MQTT.fx接入和利时互联平台( mqtt协议测试 )
    1.1新建产品  1.2 模型定义 2.1注册设备 2.2 自动生成接入凭证   3.1打开MQTT.fx进行通讯配置   平台端设备也会先显示在线;  3.2MQTT.fx发布接口和数据格式  $oc/devices/ff67d1b8a5a815bd5249d15bde1afbcc_e17961e8c3df4......
  • 从 .pfx 文件中提取证书和私钥文件
     有时需要从Windows计算机导出证书和私钥,以分离证书和密钥文件以供其他地方使用。Windows不提供完成此过程的方法。从Windows证书存储中导出证书描述了如何将证书和私钥导出到单个.pfx文件中。按照以下过程从.pfx文件中提取单独的证书和私钥文件。获取您导出的文......
  • Boris FX Silhouette 2023 for MAC 影视后期Roto抠像Paint视效合成独立版软件/Adobe插
    业界领先的rotoscoping和painttool,包含了主要的合成功能。Silhouette2023提供400多个VFX节点,包括BorisFXSapphire、MochaPro和ParticleIllusion。十五年来,Silhouette一直是好莱坞大片不可或缺的一部分,最近在《Dune》、《Spiderman:NoWayHome》、《FreeGuy》和《Th......