Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何知道缓冲通道已满_Go_Channel - Fatal编程技术网

Go 如何知道缓冲通道已满

Go 如何知道缓冲通道已满,go,channel,Go,Channel,如何知道缓冲通道已满?我不知道在缓冲通道已满时是否会被阻止,而是选择删除发送到缓冲通道的项目。您可以使用默认设置。如果无法执行任何一种情况,例如发送到完整通道,则语句将执行默认操作: package main import "fmt" func main() { ch := make(chan int, 1) // Fill it up ch <- 1 select { case ch <- 2: // Put 2 in the cha

如何知道缓冲通道已满?我不知道在缓冲通道已满时是否会被阻止,而是选择删除发送到缓冲通道的项目。

您可以使用默认设置。如果无法执行任何一种情况,例如发送到完整通道,则语句将执行默认操作:

package main

import "fmt"

func main() {
    ch := make(chan int, 1)

    // Fill it up
    ch <- 1

    select {
    case ch <- 2: // Put 2 in the channel unless it is full
    default:
        fmt.Println("Channel full. Discarding value")
    }
}
请注意,当您输入
if
块时,比较结果可能无效

相反,我选择删除发送到缓冲通道的项目

这就是所谓的“溢出通道”,你会发现安尼修斯的答案在:

元素的
:=范围通道输入{
//如果我们不能马上写下来,放下它,继续前进
挑选{

case ch.output我偶然发现的另一个有用的例子是

引自消息来源:

想法很简单:通过一个连接两个缓冲通道 将消息从传入通道转发到 传出通道。当无法在上放置新消息时 传出通道,从传出通道中取出一条消息(即 是缓冲区中最旧的消息),将其丢弃,然后放置新消息 新释放的传出通道中的消息


也请签出…

如果频道已满,我使用此代码删除一个项目。对于只有一个发送go例程的频道,它足以确保发送到
ch
之后可以正常工作

// Remove one item from chan if full
if len(ch) == cap(ch) {
    // Channel was full, but might not be by now
    select {
    case _ := <-ch:
    // Discard one item
    default:
        // Maybe it was empty already
    }
}

// Now we can send to channel
//如果已满,则从chan中删除一项
如果len(ch)=cap(ch){
//频道已满,但现在可能还没有
挑选{

一个很好的答案:溢出的通道,无论是最旧的还是最新的,都会成为工具箱中的重要工具。存在死锁的风险。将任何一个通道更改为溢出通道都可以解决此问题。丢失某些事件并不重要,如果它们是过时的,则可以轻松替换。当然有解决同一死锁问题的其他方法。问题的前提是,您希望避免通道变满。但通道可以同步,因此会阻塞两端,这是CSP思考的一个重要部分。在您更全面地理解同步之前,不要太努力地阻止缓冲区填满。正如作为练习,请尝试仅使用无缓冲通道解决几个问题。然后,您可以看到在之后添加缓冲是如何提高已在工作的系统的性能的。(有时,过多的缓冲甚至可能会降低性能。)但是,如果只想检查缓冲区是否已满,即使缓冲区未满也不向其写入数据,那该怎么办?有没有办法做到这一点?@Tom你可以实际测试len(ch)=cap(ch){…}
其中
len(ch)
是通道中的项目数,而
cap(ch)
是容量。但是,当您输入if块时,它可能无效。太好了-这是一个完整的答案!感谢您澄清if语句的结果在输入块时可能无效-我将其添加到原始答案中。如果频道已满,并且您的选择点击了
默认值
,则可能无效之后满;根据您的使用情况,
len(ch)==cap(ch)
也同样有用
for elem := range ch.input {
    // if we can't write it immediately, drop it and move on
    select {
    case ch.output <- elem:
    default:
    }
}
close(ch.output)
// Remove one item from chan if full
if len(ch) == cap(ch) {
    // Channel was full, but might not be by now
    select {
    case _ := <-ch:
    // Discard one item
    default:
        // Maybe it was empty already
    }
}

// Now we can send to channel