假设我有一个 go 接收通道。有没有一种方法可以让我同时收听所有内容?例如:
channels := make([]<-chan int, 0, N)
// fill the slice with channels
for _, channel := range channels {
<-channel
}
Run Code Online (Sandbox Code Playgroud)
这是我能做到的最接近的事情。但是,此实现取决于切片元素的顺序。
为了清楚起见,我不需要知道 go 通道的值。我只需要知道他们都完成了。
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)或外部板条箱?
我当前的功能最初是不了解上下文的。
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) 我想在后台服务中使用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) 我目前正在关注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)
第一个版本的代码产生死锁的根本原因是什么?
下面的代码工作正常
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) 我正在学习频道,下面是我尝试过的测试,但发生了死锁
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)
有人可以解释为什么会发生死锁吗?
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 …
所以我有以下测试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)
(二进制数据在两个实例中都是相同的.)
我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仍在工作?