当前位置:网站首页>[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
边栏推荐
- Ignis公链的NFT生态发展:Unicorn.art的捐赠开发之路
- 数据库之MySQL——基本常用查询命令
- Research on system and software security (I)
- 云计算技能大赛 -- openstack私有云环境 第一部分
- How to import Excel data in SQL server, 2019 Edition
- nacos源码分析思路
- 在MATLAB中快速画圆(给出圆心坐标和半径就能直接画的那种)
- Guoji Beisheng openstack container cloud environment construction
- Research on system and software security (5)
- Redis -- why is the string length of string emstr the upper limit of 44 bytes?
猜你喜欢

如何在SQL Server中导入excel数据,2019版
![[programming practice / embedded competition] learning record of embedded competition (II): picture streaming based on TCP](/img/6c/7408180d0c24560b4a68982635520e.jpg)
[programming practice / embedded competition] learning record of embedded competition (II): picture streaming based on TCP

输入 “ net start mysql ”,出现 “ 发生系统错误 5。 拒绝访问 ” 。问题详解

分布式服务治理Nacos

How to import Excel data in SQL server, 2019 Edition

一篇文章看懂变量提升(hoisting)
![云计算赛项--2020年赛题基础部分[任务3]](/img/a2/36ff5eafd18534207e6ab01422ea59.png)
云计算赛项--2020年赛题基础部分[任务3]

Sto with billing cross company inventory dump return

Dvwa 靶场练习记录

数据库之MySQL——基础篇
随机推荐
惨了,搞坏了领导的机密文件,吐血分享备份文件的代码技巧
Chapter V investment real estate
Link to some good tutorials or notes about network security and record them
KCD_ EXCEL_ OLE_ TO_ INT_ Convert reports an error sy subrc = 2
1216_MISRA_C规范学习笔记_控制流的规则要求
Concours de compétences en informatique en nuage - - première partie de l'environnement cloud privé openstack
Intranet penetration series: icmptunnel of Intranet tunnel (Master James Barlow's)
NLLLoss+log_SoftMax=CE_Loss
Implementation of promise all
Research on software security based on NLP (I)
BUUCTF [ACTF2020 新生赛]Include1
Feign source code analysis
Canvas learning Chapter 1
3C装配中的机械臂运动规划
MySQL -- the secret of lock -- how to lock data
LeetCoed18. 四数之和
[Effective Go 中文翻译]函数篇
[极客大挑战 2019]Havefun1
Internal network security attack and defense: a practical guide to penetration testing (8): Authority maintenance analysis and defense
在线YAML转XML工具