如何按顺序从多个通道接收数据?

huangapple go评论93阅读模式
英文:

How to receive data from multiple channels in sequence?

问题

我目前正在尝试使用select语句从两个通道接收数据。

select {
	case msg1 := <-ch1:
		// 发送到另一个通道
	case msg2 := <-ch2:
		// 发送到另一个通道
}

上述两个通道接收到的数据的格式如下。

type msg struct {
	msgId uint32
	data []byte
}

我想要的是将从两个通道接收到的msgmsgId进行比较,并按顺序将msg发送到另一个通道。实现这个目标的唯一方法是使用sync.Mutex来使用数据结构队列吗?

有没有一种方法可以将通过多个goroutine发送的数据按顺序发送回另一个通道?

编辑:只要顺序正确,来自两个通道的数据是排序的。数据不会完全混乱传输。

英文:

I am currently trying to receive data from two channels using a select statement.

select {
	case msg1 := &lt;-ch1:
		// send to another channel
	case msg2 := &lt;-ch2:
		// send to another channel
}

The format of the data received from the above two channels is as follows.

type msg struct {
	msgId uint32
	data []byte
}

What I want is to compare the msg received from two channels with msgId and send msg to another channel in order.

Is the only way to achieve my goal is to use sync.Mutex to use the data structure Queue?

Is there a way to send the data sent through a channel from multiple goroutines back to another channel in order?

EDIT: The data coming from the two channels is sorted as long as the order is correct. Data is not transmitted in a completely jumbled order.

答案1

得分: 1

你可以构建一个类似这样的顺序算法来缓冲乱序消息:

// 用于保存乱序消息的缓冲区
buffer := make(map[uint32]msg)
// 下一个期望的消息的ID
nextExpected := 1
for {
  select {
      case m := <-ch1:
        buffer[m.id] = m
      case m := <-ch2:
        buffer[m.id] = m
  }
  // 如果接收到了下一个期望的消息,则发送它
  for {
     if m, ok := buffer[nextExpected]; ok {
        result <- m
        delete(buffer, nextExpected)
        nextExpected++
     } else {
        break
     }
  }
}

注意:这是一个示例代码,用于演示如何构建一个缓冲乱序消息的顺序算法。具体实现可能会根据你的需求而有所不同。

英文:

You can construct an ordering algorithm that buffers out-of-order messages like this:

// Buffer to keep out-of-order messages
buffer:=make(map[uint32]msg)
// id of the next expected message
nextExpected:=1 
for {
  select {
      case m:=&lt;-ch1:
        buffer[m.id]=m
      case m:=&lt;-ch2:
        buffer[m.id]=m
  }
  // If the next expected message is received, send it
  for {
     if m,ok:=buffer[nextExpected]; ok {
        result&lt;-m
        delete(buffer,nextExpected)
        nextExpected++
     } else {
        break
     }
  }
}

huangapple
  • 本文由 发表于 2023年3月17日 09:53:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75763125.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定