标签: channel

同时收听多个 go 频道

假设我有一个 go 接收通道。有没有一种方法可以让我同时收听所有内容?例如:

channels := make([]<-chan int, 0, N)
// fill the slice with channels
for _, channel := range channels {
  <-channel
}
Run Code Online (Sandbox Code Playgroud)

这是我能做到的最接近的事情。但是,此实现取决于切片元素的顺序。

为了清楚起见,我不需要知道 go 通道的值。我只需要知道他们都完成了。

channel go goroutine

1
推荐指数
1
解决办法
1998
查看次数

如何在没有不稳定功能或外部包的情况下从 mpsc::channel 读取指定的时间?

Receiver我正在尝试在指定的时间内连续读取 a 。我想出了以下解决方案

pub fn get<T>(
    rx: &Receiver<T>,
    get_duration: time::Duration,
) -> Result<(), Err> {
    let (dur_tx, dur_rx) = channel();
    let _ = thread::spawn(move || {
        // timer to kill receiving
        thread::sleep(get_duration);
        let _ = dur_tx.send("tick");
    });

    let mut time_to_break = false;
    while time_to_break == false {
        match rx.try_recv() {
            Ok(resp) => {
                //...
            }
            Err(_) => ()
        }
        thread::sleep(time::Duration::from_millis(1)); // avoid using cpu 100%
        let _ = dur_rx.try_recv().map(|_| time_to_break = true);
    }
    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来解决这个问题,而无需不稳定或不推荐使用的功能(例如select)或外部板条箱?

timeout channel rust

1
推荐指数
1
解决办法
1210
查看次数

如果上下文被取消则终止函数执行

我当前的功能最初是不了解上下文的。

func (s *Service) ChunkUpload(r *multipart.Reader) error {
    chunk, err := s.parseChunk(r)
    if err != nil {
        return fmt.Errorf("failed parsing chunk %w", err)
    }

    if err := os.MkdirAll(chunk.UploadDir, 02750); err != nil {
        return err
    }

    if err := s.saveChunk(chunk); err != nil {
        return fmt.Errorf("failed saving chunk %w", err)
    }

    return nil
}
Run Code Online (Sandbox Code Playgroud)

我已经更新了它的方法调用,现在将 acontext.Context作为其第一个参数。我的主要目标是在上下文取消后立即终止并返回函数。

我最初的实现是这样的。

func (s *Service) ChunkUpload(ctx context.Context, r *multipart.Reader) error {
    errCh := make(chan error)

    go func() {
        chunk, err := s.parseChunk(r)
        if …
Run Code Online (Sandbox Code Playgroud)

channel go cancellation

1
推荐指数
1
解决办法
3964
查看次数

后台任务中的.Net Core 通道

我想在后台服务中使用chanel,但是在运行我的代码时出现此错误,我需要做什么。

抱歉英语不好

尝试激活“SendEmailService”时无法解析类型“System.Threading.Channels.ChannelReader`1[SendMailChanel]”的服务

public class SendMailChanel
    {
        public List<SendMail> SendMails { get; set; }
        public List<string> MailTos { get; set; }
    }

public class SendEmailService: BackgroundService
{
      
        private readonly ChannelReader<SendMailChanel> _channel;

        public HostedService(         
            ChannelReader<SendMailChanel> channel)
        {
            _channel = channel;
        }

        protected override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            await foreach (var item in _channel.ReadAllAsync(cancellationToken))
            {
                try
                {
                    // do your work with data
                }
                catch (Exception e)
                {
                    
                }
            }
        }
}

[ApiController]
[Route("api/data/upload")]
public class UploadController : ControllerBase
{
    private …
Run Code Online (Sandbox Code Playgroud)

c# channel .net-core

1
推荐指数
1
解决办法
3388
查看次数

无缓冲通道上的死锁

我目前正在关注go教程,并进入了有关通道的部分,当我进行一些测试时,我发现了一个我很难理解的奇怪行为

以下代码会产生死锁错误

package main

import "fmt"

func main() {
    c := make(chan string)
    c <- "test"
    fmt.Printf("%v", <- c)
}
Run Code Online (Sandbox Code Playgroud)

但执行以下操作之一可以修复代码

使用缓冲通道:

package main

import "fmt"

func main() {
    c := make(chan string, 1)
    c <- "test"
    fmt.Printf("%v", <- c)
}
Run Code Online (Sandbox Code Playgroud)

或将值设置为不同线程上的通道

package main

import "fmt"

func main() {
    c := make(chan string)
    go func(){c <- "test"}()
    fmt.Printf("%v", <- c)
}
Run Code Online (Sandbox Code Playgroud)

第一个版本的代码产生死锁的根本原因是什么?

channel go

1
推荐指数
1
解决办法
651
查看次数

我可以不使用 make 函数来创建频道吗?

下面的代码工作正常

func main() {
    c := make(chan string)
    go subRountine(c)
    fmt.Println(<-c)
}

func subRountine(c chan string) {
    c <- "hello"
}

Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以不使用 make 函数来创建通道?像这样的东西,但这个示例不起作用

func main() {
    var c chan string
    go subRountine(c)
    fmt.Println(<-c)
}

func subRountine(c chan string) {
    c <- "hello"
}

Run Code Online (Sandbox Code Playgroud)

channel go

1
推荐指数
1
解决办法
688
查看次数

当我在 goroutine 中添加 select default 语句时通道死锁

我正在学习频道,下面是我尝试过的测试,但发生了死锁

func main() {
    ch := make(chan int)
    go func() {
        select {
        case ch <- 1:
            fmt.Println("send suc")
        default: // if comment this line, it will run smoothly
            fmt.Println("default")
        }
    }()
    time.Sleep(2) // do some time consuming thing...
    fmt.Printf("receive val: %d", <-ch)
}
Run Code Online (Sandbox Code Playgroud)

我预计不会出现僵局,但结果是:

default
fatal error: all goroutines are asleep - deadlock!
Run Code Online (Sandbox Code Playgroud)

但如果我删除defaultor time.Sleep(2),代码将顺利运行,结果:

send suc
receive val: 1
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么会发生死锁吗?

deadlock channel go

1
推荐指数
1
解决办法
55
查看次数

mpsc channels stucking at the receiver

use std::sync::Arc;

use tokio::sync::mpsc;

async fn student(id : i32,tx : Arc<mpsc::Sender<String>>) {
    println!("student {} is getting their hw.",id);
    tx.send(format!("student {}'s hw !",id)).await.unwrap();
}

async fn teacher(mut rc : mpsc::Receiver<String>) -> Vec<String> {
    let mut homeworks = Vec::new();
    while let Some(hw) = rc.recv().await {
        println!("{hw}");
        homeworks.push(hw);
    }
    homeworks
}

#[tokio::main]
async fn main() {
    let (tx,rc): (mpsc::Sender<String>, mpsc::Receiver<String>) = mpsc::channel(100);
    let ch_arc: Arc<mpsc::Sender<String>> = Arc::new(tx);
    
    for i in 0..10 {
        tokio::task::spawn(student(i,ch_arc.clone()));
    }
    let hws = teacher(rc).await;
    println!("{:?}",hws);
}
Run Code Online (Sandbox Code Playgroud)

I am currently …

channel rust rust-tokio mpsc

1
推荐指数
1
解决办法
61
查看次数

从stdin接收二进制数据,发送到Go中的通道

所以我有以下测试Go代码,它设计用于通过stdin读取二进制文件,并将读取的数据发送到通道,然后进一步处理.在我在这里给出的版本中,它只从stdin中读取前两个值,尽管就显示问题而言这很好.

package main

import (
    "fmt"
    "io"
    "os"
)

func input(dc chan []byte) {
    data := make([]byte, 2)
    var err error
    var n int
    for err != io.EOF {
        n, err = os.Stdin.Read(data)
        if n > 0 {
            dc <- data[0:n]
        }
    }
}

func main() {
    dc := make(chan []byte, 1)
    go input(dc)
    fmt.Println(<-dc)
}
Run Code Online (Sandbox Code Playgroud)

为了测试它,我首先使用go build构建它,然后使用命令向它发送数据 -

./inputtest < data.bin
Run Code Online (Sandbox Code Playgroud)

我目前用来测试的数据只是使用openssl命令创建的随机二进制数据.

我遇到的问题是它错过了Stdin的第一个值,只给出了第二个和更大的值.我认为这与通道有关,因为移除通道的相同脚本会生成正确的数据.有没有人遇到过这个?例如,运行此命令时,我得到以下输出 -

./inputtest < data.bin
[36 181]
Run Code Online (Sandbox Code Playgroud)

我应该得到 -

./inputtest < data.bin
[72 218]
Run Code Online (Sandbox Code Playgroud)

(二进制数据在两个实例中都是相同的.)

binary stdin channel go

0
推荐指数
1
解决办法
899
查看次数

选择忽略慢的情况?

select在多个案例中使用这样的:

for {
    select {
    case data:= <- highFreqChan:
        // do something:
    case <- time.After(time.Second * 5):
        // send some heartbeat like data...
    }
}
Run Code Online (Sandbox Code Playgroud)

我发现,如果highFreqChan获得了大量数据,心跳情况就不会进入,当停止发送数据时highFreqChan,心跳情况再次存活,如何让它始终进入心跳情况而highFreqChan仍在工作?

channel go

0
推荐指数
1
解决办法
50
查看次数

标签 统计

channel ×10

go ×7

rust ×2

.net-core ×1

binary ×1

c# ×1

cancellation ×1

deadlock ×1

goroutine ×1

mpsc ×1

rust-tokio ×1

stdin ×1

timeout ×1