当前位置:网站首页>[go] common concurrency model [generic version]
[go] common concurrency model [generic version]
2022-04-23 08:08:00 【CRAJA】
Conclusion in 《go The way of language concurrency 》
package common
import "sync"
// Bridge By accepting transmission chan Of chan, Pass the value back to ( This is to read one in order channel Will choose the next channel)
func Bridge(done <-chan interface{
}, chanStream <-chan <-chan any) <-chan any {
valStream := make(chan any)
go func() {
defer close(valStream)
for {
var stream <-chan any
select {
case mybeStream, ok := <-chanStream: // Read chanStream Medium channel
if !ok {
return
}
stream = mybeStream
case <-done:
return
}
for val := range OrDone(done, stream) {
// Read channel Send the content back
select {
case <-done:
return
case valStream <- val:
}
}
}
}()
return valStream
}
// Tee Read in Data and send it to two accepted at the same time channel
func Tee(done <-chan interface{
}, in <-chan any) (_, _ <-chan any) {
out1 := make(chan any)
out2 := make(chan any)
go func() {
defer close(out1)
defer close(out2)
for v := range OrDone(done, in) {
var out1, out2 = out1, out2 // Local version , Hide external variables
for i := 0; i < 2; i++ {
// To ensure two channel Can be written. We use two writes
select {
case <-done:
return
case out1 <- v:
out1 = nil // Close copy after simultaneous write channel To block and prevent secondary writes
case out2 <- v:
out2 = nil
}
}
}
}()
return out1, out2
}
// OrDone adopt done To control reading chan
func OrDone(done <-chan interface{
}, c <-chan any) <-chan any {
valStream := make(chan any)
go func() {
defer close(valStream)
for {
select {
case <-done:
return
case v, ok := <-c:
if ok == false {
return
}
select {
// It can be optimized
case valStream <- v:
case <-done:
}
}
}
}()
return valStream
}
// MyInteger Integer types , For random number type conversion
type MyInteger interface {
~int | ~int32 | ~int64
}
// MyFloat Floating point numbers , Can be used for addition, subtraction, multiplication and division
type MyFloat interface {
~float64 | ~float32
}
// Number Can be used for addition, subtraction, multiplication and division
type Number interface {
MyFloat | MyInteger
}
// FanIn From many channels Merge data into one channel
func FanIn(done <-chan interface{
}, channels []<-chan any) <-chan any {
var wg sync.WaitGroup
multiplexedStream := make(chan any)
multiplex := func(c <-chan any) {
defer wg.Done()
for i := range c {
select {
case <-done:
return
case multiplexedStream <- i:
}
}
}
wg.Add(len(channels))
for _, c := range channels {
go multiplex(c)
}
go func() {
wg.Wait()
close(multiplexedStream)
}()
return multiplexedStream
}
// Multiply Multiplication
func Multiply[V Number](done <-chan interface{
}, valueStream <-chan V, multiplier V) <-chan V {
results := make(chan V)
go func() {
defer close(results)
for v := range valueStream {
select {
case <-done:
return
case results <- v * multiplier:
}
}
}()
return results
}
// Add Add
func Add[V Number](done <-chan interface{
}, valueStream <-chan V, additive V) <-chan V {
results := make(chan V)
go func() {
defer close(results)
for v := range valueStream {
select {
case <-done:
return
case results <- v + additive:
}
}
}()
return results
}
// ToType Explicitly convert to the corresponding type
func ToType[T any](done <-chan interface{
}, valueStream <-chan interface{
}) <-chan T {
stringStream := make(chan T)
go func() {
defer close(stringStream)
for v := range valueStream {
select {
case <-done:
return
case stringStream <- v.(T):
}
}
}()
return stringStream
}
// PrimeFinder Get and judge prime numbers
func PrimeFinder[T MyInteger](done <-chan interface{
}, intStream <-chan T) <-chan interface{
} {
results := make(chan interface{
})
go func() {
defer close(results)
for v := range intStream {
select {
case <-done:
return
default:
}
for i := T(2); i*i < v; i++ {
if v%i == 0 {
goto next
}
}
results <- v
next:
}
}()
return results
}
// Take Take out num End after number
func Take(done <-chan interface{
}, valueStream <-chan any, num int) <-chan any {
results := make(chan any)
go func() {
defer close(results)
for i := 0; i < num; i++ {
select {
case <-done:
return
case results <- <-valueStream:
}
}
}()
return results
}
// RepeatFn Call the function repeatedly
func RepeatFn(done <-chan interface{
}, fn func() interface{
}) <-chan interface{
} {
results := make(chan interface{
})
go func() {
defer close(results)
for {
select {
case <-done:
return
case results <- fn():
}
}
}()
return results
}
// Repeat Duplicate generated value
func Repeat(done <-chan interface{
}, values ...any) <-chan any {
valueStream := make(chan any)
go func() {
defer close(valueStream)
for {
for _, v := range values {
select {
case <-done:
return
case valueStream <- v:
}
}
}
}()
return valueStream
}
The details are in Warehouse
There is no need to use generics in many places , Unless basically written as like as two peas of wheels, it is recommended to use for many types. , Advice to see go Official instruction course , I think this generic is OK , Not ugly
版权声明
本文为[CRAJA]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230645168316.html
边栏推荐
- 数据库之MySQL——基本常用查询命令
- 利用sqlmap注入获取网址管理员账号密码
- [Effective Go 中文翻译] 第一篇
- 一篇文章看懂变量提升(hoisting)
- Buuctf misc brush questions
- [problem solving] vs2019 solves the problem that the EXE file generated by compilation cannot be opened
- LeetCode 1611. 使整数变为 0 的最少操作次数
- MySQL -- the secret of lock -- how to lock data
- 云计算技能大赛 -- openstack私有云环境 第一部分
- Principle of sentinel integrating Nacos to update data dynamically
猜你喜欢
BUFFCTF文件中的秘密1
Intranet penetration series: icmptunnel of Intranet tunnel (Master James Barlow's)
Draw a circle quickly in MATLAB (the one that can be drawn directly given the coordinates and radius of the center of the circle)
BUUCTF [极客大挑战 2019]EasySQL1
数据库之Mysql——概述安装篇
[programming practice / embedded competition] learning record of embedded competition (I): establishment of TCP server and web interface
Go语学习笔记 - 结构体 | 从零开始Go语言
Sto with billing cross company inventory dump return
利用sqlmap注入获取网址管理员账号密码
智能名片小程序名片详情页功能实现关键代码
随机推荐
NIH降血脂指南《your guide to lowering your Cholesterol with TLC》笔记(持续更新中)
Introduction to sap query enhanced development
Anti shake and throttling
Ribbon启动流程
Research on system and software security (2)
Feign source code analysis
Ctf-misc summary
Talk about the essence of interface idempotent and consumption idempotent
数据库之Mysql——概述安装篇
Redis事务实现乐观锁原理
【问题解决】VS2019解决编译生成的exe文件打不开的情况
Redis transaction implements optimistic locking principle
Move layout (Flex layout, viewport label)
从ES、MongoDB、Redis、RocketMQ出发谈分布式存储
Ignis公链的NFT生态发展:Unicorn.art的捐赠开发之路
输入 “ net start mysql ”,出现 “ 发生系统错误 5。 拒绝访问 ” 。问题详解
高精度焊接机械臂定位
KVM安装部署
【编程实践/嵌入式比赛】嵌入式比赛学习记录(二):基于TCP的图片流传输
一篇文章看懂变量提升(hoisting)