-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Feature request: non-blocking take!
#45902
Comments
I guess it's possible to write a |
Wouldn't that require creating a new |
Xref #41966, which implements |
No, I don't see that it would require multiple Channels. |
Note |
I may be misunderstanding your suggestion--if the while !done
workqueue = Channel{Blah}(blah)
for i=1:something
put!(i, workqueue)
end
# workqueue gets closed once it's exhausted for this iteration
end ...doesn't that mean I'd need another? Or is there a way to reconstitute a I'm also not sure where I would put an |
I think the key point @JeffBezanson made above was:
In other words, only workers do work, having an extra one means all threads are busy and the main thread doesn't have to help out, so it doesn't need a non-blocking take. [Putting words in Jeffs mouth which he may spit out :-)] |
@elextr ah, gotcha--that was the original plan, but I'm not sure how to keep the main thread out of the way (rather than just busy-waiting); I tried ...
while workremains
yield()
end
... ...but it gave very poor performance, with usually about 40% of the time spent in |
That would be expected, its consuming CPU constantly because its non-blocking. Make type At least thats what I think Jeff suggested. [Edit: or use this for the putter] |
Yes that is what I meant! It probably isn't necessary to define a sentinel type though; you could use |
Also, as the OP indicated, the best solution would be to |
It would be nice to have a non-blocking
take!
to pull work from aChannel
without hanging.My particular use case is for a program with small units of work that can't be grouped into larger sets because each iteration relies on the results of the last. With so little to do for each unit of work, spawning a task for every one is a lot of overhead, so I would like to use long-lived tasks that repeatedly pull work from a shared queue until the simulation is finished. Here's some pseudocode demonstrating the concept:
For this particular case, the body of the loop in which the main thread takes work from the queue could conceptually be replaced by
yield()
, but that doesn't seem to perform well from what I've seen. Even ifyield()
could work in that case, though, I have to imagine there are other cases where not having a non-blockingtake!
makes life harder.The text was updated successfully, but these errors were encountered: