New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
runtime: blocked channel operations starvation #21187
Comments
Have you tried on 1.9rc1? What about other operating systems, like Linux? Also CC @aclements |
@mvdan not yet. I find it hard to reproduce in my program. |
I don't see a bug in the playground code in the last comment. It's true that the number of values sent on the different channels can be very unequal, but that is not a bug. It also doesn't seem to directly correspond to the original problem description, which was about multiple receiving goroutines rather than multiple sending goroutines. With multiple receiving goroutines, it's still not a bug if one of them is starved. Why does it matter as long as all the values sent on the channel are being delivered to some goroutine? |
@ianlancetaylor I was talking about multiple sending go-routines. One can starve and it's message |
Your playground example does show that if the sending goroutines do a busy loop, then one or more them can starve sending a value. I'm not sure what, if anything, we can do about that. As you say above, it's possible to restructure the program to avoid the problem. Other than that, it's usually a good idea for a single processor to keep running the same set of goroutines, and it's usually a good idea to start the goroutine receiving from a channel when a channel is full (though I'm not sure the current scheduler actually does this). For an example like your playground example, it's possible for the sending and receiving goroutine to be on the same processor, and for that processor to keep flipping back and forth and, apparently, to tie up the channel sufficiently that no other goroutine gets in. But anything we do to change that will tend to slow down the scheduler and may penalize other programs. It's not obvious to me that we want to optimize for the case of multiple goroutines sending to the same channel in a busy loop. Of course if you have any suggestions I would like to hear them. |
I think @rsc derscribed it best (#11506)
I believe that a channel should be FIFO when multiple senders are blocked. |
#11506 <#11506> was not implemented due
to the last two comments on that issue. Neither this thread nor the
literature has added any additional performance numbers, throughput or
latency, to warrant reconsideration. On the other hand the conjecture that
other schedules can be built on top of drive-by/barging has been confirmed
with the simple code provided above.
…On Sat, Jul 29, 2017 at 1:01 PM, johnsnow4514 ***@***.***> wrote:
I think @rsc <https://github.com/rsc> derscribed it best (#11506
<#11506>)
Especially since so many Go programs care about latency, making channels
first come, first served seems worth doing. And it looks to me like it can
be done trivially and at no performance cost. The current behavior looks
more like a bug than an intended result.
I believe that a channel should be FIFO when multiple senders are blocked.
The first sender to get blocked should be the first to be released.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#21187 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AA7Wn3xjHen3h9HAe5gybYCgTm9teYdtks5sS2VNgaJpZM4Ok7vj>
.
|
As far as I can tell there is nothing to do here. Please comment if you disagree. |
What version of Go are you using (
go version
)?1.8.0
What operating system and processor architecture are you using (
go env
)?windows/amd64
What did you do?
Related to #11506
I have a messaging app that generates messages and passes them using a channel to
go-routines whose job is to transform those messages into small packets of data which then passes
using another channel to go-routines whose job is to read the packets and send them using a socket.
What did you expect to see?
packets that are generated at some point in time should be sent around the same time.
there shouldn't be more than a few milliseconds between sending a packet to a channel and receiving it
on the receiving go-routine.
What did you see instead?
In some cases a go-routine might starve for like 30 seconds while other packets are transferred just fine.
This causes problems in my app and I had to implement my own wrap around a channel to insure FIFO
ordering which fixed the problem.
is there any plans to fix #11506 ? @rsc @randall77
it really causes weird and rare behaviors in production environments
Here's my implementation for FIFO channeling if anyone is facing the same problem...
The text was updated successfully, but these errors were encountered: