何时在netty中使用Unpooled(when to use Unpooled in netty)

我想知道何时在Netty中使用Unpooled 。 一些示例显示在Unpooled.wrappedBuffer包装了byte [],并且一些示例仅显示

ctx.writeAndFlush(bytes); // where bytes is just byte[]

是否有关于何时使用Unpooled的指南?


I'm trying to figure out when to use Unpooled in Netty. Some examples show wrapped the byte[] in Unpooled.wrappedBuffer, and some examples show just

ctx.writeAndFlush(bytes); // where bytes is just byte[]

Is there a guideline on when to use Unpooled?


原文:https://stackoverflow.com/questions/45291211
2022-10-06 10:10

满意答案

这样写的代码会产生一个死锁。 但是,渠道不一定要关闭。 有多种方法可以解决此问题。

例如,你可以通过以下方法替换for / select循环:

n := len(requests)
for r := range ch {
    processResponse(r)
    n--
    if n == 0 {
        break
    }
}

这里我们假设潜在的超时在每个goroutine中进行管理。

另一个真正依赖关闭频道的解决方案可以写成如下:

func asyncHttpGets(requests []HttpRequest) {

    ch := make(chan *HttpResponse)
    var wg sync.WaitGroup
    for _, request := range requests {
        wg.Add(1)
        go func(r HttpRequest) {
            defer wg.Done()
            resp, err := http.Get(r.url)
            ch <- &HttpResponse{r, resp, err}
        }(request)
    }

    go func() {
        wg.Wait()
        close(ch)
    }()
    for r := range ch {
        processResponse(r)
    }
}

请注意,比较初始代码,请求变量不是从goroutine访问的,而是作为参数传递的。 因此,通过通道发布的输出数据结构是一致的。 这是初始代码中的一个问题。 有关此特定主题的更多信息,请访问: https//github.com/golang/go/wiki/CommonMistakes

另一种解决方案是使用原子计数器计数goroutine中的响应,并在计数器达到极限时明确关闭通道。 但是处理同步/原子常常容易出错,所以在这里可能不是个好主意。

最后,有时您需要获得更多控制权才能正确管理超时,错误等... Tomb包可以帮助您以安全的方式管理goroutines的生命周期。

请参阅https://github.com/go-tomb/tomb/tree/v2


The code, written like this, will produce a deadlock. But, the channel does not have necessarily to be closed. There are multiple ways to solve this issue.

For instance, you could replace the for/select loop by:

n := len(requests)
for r := range ch {
    processResponse(r)
    n--
    if n == 0 {
        break
    }
}

Here we assume that the potential timeouts are managed in each goroutine.

Another solution, which really relies on closing the channel could be written as follows:

func asyncHttpGets(requests []HttpRequest) {

    ch := make(chan *HttpResponse)
    var wg sync.WaitGroup
    for _, request := range requests {
        wg.Add(1)
        go func(r HttpRequest) {
            defer wg.Done()
            resp, err := http.Get(r.url)
            ch <- &HttpResponse{r, resp, err}
        }(request)
    }

    go func() {
        wg.Wait()
        close(ch)
    }()
    for r := range ch {
        processResponse(r)
    }
}

Note that compared the initial code, the request variable is not accessed from the goroutine, but passed as a parameter. The output data structure posted via the channel is therefore consistent. This was an issue in the initial code. See more information about this specific topic at: https://github.com/golang/go/wiki/CommonMistakes

Yet another solution would be to count the responses in the goroutines using an atomic counter, and explicitly close the channel when the counter reaches the limit. But dealing with sync/atomic is often error-prone, so it is probably not a good idea here.

Finally, sometimes you need to get more control in order to properly manage timeouts, errors, etc ... The tomb package can help you to manage the lifecycle of the goroutines in a safe way.

See https://github.com/go-tomb/tomb/tree/v2

相关问答

更多

为什么golang的频道需要一个去程序?(Why does a channel in golang require a go-routine?)

默认情况下,发送和接收阻塞,直到另一侧准备就绪。 确切地说:因为没有去程序正在等待接收,所以发送被阻塞,并且程序死锁。 发送操作不会被跳过,因为没有人正在等待接收。 如果你想做一个非阻塞发送,你可以在一个带默认情况的select语句中使用send操作符: select { case c <- 17: default: } By default, sends and receives block until the other side is ready. Exactly: since no go...

使用Google Channel API关闭频道(Closing Channel with Google Channel API)

显然,互联网上没有人想出(或需要弄清楚)如何做到这一点,所以我只是盯着API概述足够长的时间,直到它来到我身边。 当您创建“socket”变量时,秘密在API的Javascript部分。 Javascript API声明套接字var还具有“close()”函数。 考虑到我用Java编写了我的实现,这对我来说有点棘手,因为我不得不抹去我对JSNI的了解,而socket var仅在我的“join”调用期间存在。 为了解决这个问题,我在套接字变量中创建了一个全局变量,在本例中称为“globalSocke...

golang频道无法使用或发布(golang channel can't consume or publish)

我不确定你想要实现的目标。 但是您的示例代码可以保证在select语句中阻塞。 select的default情况用于在通道上的特定读取或写入不成功时提供回退。 这意味着在您的代码中,始终执行默认情况。 在选择开始之前,没有任何值写入通道,因此case语句永远不会运行。 default情况下的代码永远不会成功并无限期阻塞,因为通道中没有空间来存储值,而其他任何人都没有从中读取任何其他goroutine。 解决您当前问题的简单方法是: stopSvr=make(chan bool, 1) // 1 s...

Golang - 为什么要使用完成的频道(Golang - Why use done channel)

没有结果是不一样的: 在许多情况下(例如,不同的CPU负载,它是非确定性和系统依赖的行为),您的主要参数会在您received job之前退出,所以您不能保证all jobs received ,例如只是添加 time.Sleep(500) 之前 fmt.Println("received job", j) 看看这个,在The Go Playground上试试看: // _Closing_ a channel indicates that no more values // will be s...

Golang频道睡着了(Golang channel is asleep)

这是因为主要的goroutine卡in in <- true 另一个goroutine卡住out out <- 1 如果你写出一个case它应该工作: for { select { case <-in: fmt.Println("Close") close(out) return case out <- 1: fmt.Println("Out") break } } This is...

GoLang:关闭频道(Golang: Closing a channel)

这样写的代码会产生一个死锁。 但是,渠道不一定要关闭。 有多种方法可以解决此问题。 例如,你可以通过以下方法替换for / select循环: n := len(requests) for r := range ch { processResponse(r) n-- if n == 0 { break } } 这里我们假设潜在的超时在每个goroutine中进行管理。 另一个真正依赖关闭频道的解决方案可以写成如下: func asyncHttpGe...

Golang频道维护(Golang Channel Maintenance)

通常的做法是通过超时提供通道读取和写入。 这是一种安全措施,可确保在给定的时间间隔过后,goroutine停止阻塞。 一个用例就是启动N个例程以在各种http客户端上执行异步搜索。 你会想要尽可能多地等待结果,但你不想永远等待。 这些http获取程序将执行查询并将结果发送给您,前提是它们可以在设置超时内完成任务。 这是该原则的简单版本。 你可以在Go游乐场上运行它。 这里唯一的区别是goroutine正在从我们的队列通道读取,而不是向我们发送数据的那个。 但原则是相同的。 package main...

使用golang频道。(using golang channels. GETTING “all goroutines are asleep - deadlock!”)

在调用wg.Wait()之前,对wg.Wait()的调用不会返回。 在addStuff() ,当没有其他goroutine来消耗这些值时,你addStuff()值写入通道。 由于通道是无缓冲的,因此对channel <- val的第一次调用将永远阻塞,从而导致死锁。 此外, addStuff()的通道仍为零,因为您在main中创建了一个新的变量绑定,而不是分配给包级变量。 写入nil通道会永久阻塞: channel := make(chan int) //doesn't affect the pa...

Golang goroutine没有使用在频道上使用范围的功能延迟(Golang goroutine not running defer with function that uses range on channel)

延迟函数未执行的原因是应用程序到达main函数的末尾,导致整个程序终止而不等待goroutine。 Go规范说: 当函数main返回时,程序退出。 它不等待其他(非主要)goroutines完成。 由于你的recieveCakeAndPack仍在等待频道关闭(从未发生),它将永远不会在程序终止之前推迟。 编辑 另一方面 - 将延迟语句最后放在函数中是没有意义的。 而是将它们直接放在要延迟的语句之后,例如: fmt.Println("Entering function") defer fmt.Pri...

golang:如何在所有goroutine完成后关闭频道?(golang: how to close the channel after all goroutines are finished?)

对我来说,它看起来并不像你正在从你的频道中读取,并且因为它是一个同步频道(你从未在其上声明长度),如果它收到一个值,它将阻止。 所以你需要通过value <- c读取你的c ,否则你的获取函数只会挂在c <- *e 这导致你的sync.WaitGroup从不wg.Done()从不递减计数器,这永远不会导致wg.Wait()停止阻塞,这导致你的close(c)永远不会被调用 To me it doesn't look like you're reading from your channel, an...

相关文章

更多

[Netty 1] 初识Netty

1. 简介 最早接触netty是在阅读Zookeeper源码的时候,后来看到Storm的消息传输层也由 ...

Netty环境配置

netty是一个java事件驱动的网络通信框架,也就是一个jar包,只要在项目里引用即可。

Netty开发环境配置

最新版本的Netty 4.x和JDK 1.6及更高版本

Netty源码分析

Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户 ...

storm学习之Netty代替ZMQ

整理自 http://www.csdn.net/article/2014-08-04/2821018/ ...

Netty基于流的传输处理

​在TCP/IP的基于流的传输中,接收的数据被存储到套接字接收缓冲器中。不幸的是,基于流的传输的缓冲器 ...

Netty入门实例-时间服务器

Netty中服务器和客户端之间最大的和唯一的区别是使用了不同的Bootstrap和Channel实现

Netty入门实例-使用POJO代替ByteBuf

使用TIME协议的客户端和服务器示例,让它们使用POJO来代替原来的ByteBuf。

在Twitter,Netty 4 GC开销降为五分之一

原文:http://www.infoq.com/cn/news/2013/11/netty4-twit ...

Netty入门实例-编写服务器端程序

channelRead()处理程序方法实现如下

最新问答

更多

获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)

我用Google搜索了一个解决方案。 “EnumDisplayModeProvider”是我自己设置网站的各种模式的枚举。 public EnumDisplayModeProvider GetDisplayModeId() { foreach (var mode in DisplayModeProvider.Instance.Modes) if (mode.CanHandleContext(HttpContext)) {

如何通过引用返回对象?(How is returning an object by reference possible?)

这相对简单:在类的构造函数中,您可以分配内存,例如使用new 。 如果你制作一个对象的副本,你不是每次都分配新的内存,而是只复制指向原始内存块的指针,同时递增一个也存储在内存中的引用计数器,使得每个副本都是对象可以访问它。 如果引用计数降至零,则销毁对象将减少引用计数并仅释放分配的内存。 您只需要一个自定义复制构造函数和赋值运算符。 这基本上是共享指针的工作方式。 This is relatively easy: In the class' constructor, you allocate m

矩阵如何存储在内存中?(How are matrices stored in memory?)

正如它在“熵编码”中所说的那样,使用Z字形图案,与RLE一起使用,在许多情况下,RLE已经减小了尺寸。 但是,据我所知,DCT本身并没有给出稀疏矩阵。 但它通常会增强矩阵的熵。 这是compressen变得有损的点:输入矩阵用DCT传输,然后量化量化然后使用霍夫曼编码。 As it says in "Entropy coding" a zig-zag pattern is used, together with RLE which will already reduce size for man

每个请求的Java新会话?(Java New Session For Each Request?)

你是如何进行重定向的? 您是否事先调用了HttpServletResponse.encodeRedirectURL()? 在这里阅读javadoc 您可以使用它像response.sendRedirect(response.encodeRedirectURL(path)); The issue was with the path in the JSESSIONID cookie. I still can't figure out why it was being set to the tomca

css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)

我认为word-break ,如果你想在一个单词中打破行,你可以指定它,这样做可以解决问题: .column { word-break:break-all; } jsFiddle演示。 您可以在此处阅读有关word-break属性的更多信息。 I think word-break, with which you can specify if you want to break line within a word, will do the trick: .column { word-break

无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)

我认为您忘记在分类时间内缩放输入图像,如train_test.prototxt文件的第11行所示。 您可能应该在C ++代码中的某个位置乘以该因子,或者使用Caffe图层来缩放输入(请查看ELTWISE或POWER图层)。 编辑: 在评论中进行了一次对话之后,结果发现在classification.cpp文件中错误地删除了图像均值,而在原始训练/测试管道中没有减去图像均值。 I think you have forgotten to scale the input image during cl

xcode语法颜色编码解释?(xcode syntax color coding explained?)

转到: Xcode => Preferences => Fonts & Colors 您将看到每个语法高亮颜色旁边都有一个简短的解释。 Go to: Xcode => Preferences => Fonts & Colors You'll see that each syntax highlighting colour has a brief explanation next to it.

在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)

你考虑过第三方拼写检查吗? 您可以将在C#中开发的自定义WinForms控件插入访问数据库吗? VB6控件怎么样? 如果你能找到一个使用第三方库进行拼写检查的控件,那可能会有效。 Have you considered a third party spell checker? Can you insert a custom WinForms controls developed in C# into an access database? What about a VB6 control? If

从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)

我有同样的问题,因为我在远程服务器上有两个图像,我需要在每天的预定义时间复制到我的本地服务器,这是我能够提出的代码... try { if(@copy('url/to/source/image.ext', 'local/absolute/path/on/server/' . date("d-m-Y") . ".gif")) { } else { $errors = error_get_last(); throw new Exception($err

从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))

我不确定我完全明白你在说什么。 你能编辑你的帖子并包含你正在做的Subversion命令/操作的特定顺序吗? 最好使用命令行svn客户端,以便容易为其他人重现问题。 如果您只是想获取文件的旧副本(即使该文件不再存在),您可以使用如下命令: svn copy ${repo}/trunk/moduleA/file1@${rev} ${repo}/trunk/moduleB/file1 其中${repo}是您的存储库的URL, ${rev}是您想要的文件的版本。 这将恢复该文件的旧版本,包括最高版本