Skip to content
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

Multiprocessing: Expose underlying pipe in queues #48081

Open
TarkaSteve mannequin opened this issue Sep 11, 2008 · 8 comments
Open

Multiprocessing: Expose underlying pipe in queues #48081

TarkaSteve mannequin opened this issue Sep 11, 2008 · 8 comments
Labels
extension-modules C modules in the Modules dir topic-multiprocessing type-feature A feature request or enhancement

Comments

@TarkaSteve
Copy link
Mannequin

TarkaSteve mannequin commented Sep 11, 2008

BPO 3831
Nosy @anacrolix

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2008-09-11.01:13:58.188>
labels = ['extension-modules', 'type-feature']
title = 'Multiprocessing: Expose underlying pipe in queues'
updated_at = <Date 2014-02-27.22:38:01.352>
user = 'https://bugs.python.org/TarkaSteve'

bugs.python.org fields:

activity = <Date 2014-02-27.22:38:01.352>
actor = 'jmehnle'
assignee = 'jnoller'
closed = False
closed_date = None
closer = None
components = ['Extension Modules']
creation = <Date 2008-09-11.01:13:58.188>
creator = 'TarkaSteve'
dependencies = []
files = []
hgrepos = []
issue_num = 3831
keywords = []
message_count = 6.0
messages = ['73001', '73019', '73069', '85168', '107371', '133358']
nosy_count = 9.0
nosy_names = ['forest', 'roudkerk', 'jnoller', 'TarkaSteve', 'asksol', 'anacrolix', 'andresfreund', 'jmehnle', 'barcc']
pr_nums = []
priority = 'low'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue3831'
versions = ['Python 3.2']

@TarkaSteve
Copy link
Mannequin Author

TarkaSteve mannequin commented Sep 11, 2008

Both Connection and Pipe objects expose their underlying file
descriptors, which is useful for accessing them in an event-driven
manner. However the higher-level Queue does not make the underlying
pipe available; to get at them you must access private member attributes
which is fragile. It would be good to have a well-defined API for
accessing either the pipe objects or the underlying FDs.

@TarkaSteve TarkaSteve mannequin added extension-modules C modules in the Modules dir type-feature A feature request or enhancement labels Sep 11, 2008
@jnoller
Copy link
Mannequin

jnoller mannequin commented Sep 11, 2008

Steve, I'm a little nervous about exposing the underlying Queue pipes in
an official API simply due to the fact that it is an advanced use case,
and we do want to keep the API simple, and relatively close to the core
Queue implementation.

Do you have an example use-case/code? This will not be making it into
python 2.6/3.0 - it will need to wait until 2.7 and 3.1 at very least.

@TarkaSteve
Copy link
Mannequin Author

TarkaSteve mannequin commented Sep 12, 2008

Hi Jesse,

The use-case I had is mind is enabling asyncronous (i.e. select() style)
notification of data being available on the queue, which is more elegant
(and efficient) than polling with get(). Example code showing how this
works with GTK is available here:

http://haltcondition.net/?p=2319

I understand wanting to keep the API simple, however the underlying
posix-level file-descriptors for pipes and connections are already
exposed via fileno(); the actual API change would just be a matter of
changing '_reader' and '_writer' to 'reader' and 'writer' (implicitly
guaranteeing their consistency).

Would it help if I attached a patch showing the proposed change to the
module? I realise the API is frozen now but it would be nice to have
this further down the line.

@jnoller
Copy link
Mannequin

jnoller mannequin commented Apr 2, 2009

Can you please provide an example w.r.t to how you would handle the case
where poll()/recv returns partial bytes of the object instead of a full
object?

@andresfreund
Copy link
Mannequin

andresfreund mannequin commented Jun 9, 2010

As soon as some bytes are signalled as being available one can simply do a normal get(). I don't really see the problem here?
Sure, the get() might not be completely non-blocking (especially if the transferred event is more than the size of a pipe-buffer) but I have a hard time seing that as a problem as that should be both rare and only last a short time.

My personal use-case is being able to efficiently wait for evens from different queues - using the standard api one currently can only do that by busy looping...

The biggest thing I see where you have to be careful here is some stomping herd phenomenon you will get into if you have multiple readers doing a poll().
Namely *all* off those processes will awake and run into .get() which isnt exactly nice, but thats hardly solvable on python level.

@anacrolix
Copy link
Mannequin

anacrolix mannequin commented Apr 9, 2011

I look forward to this, or something similar. Inspiration can be taken from Golangs's select behaviour on channels.

select {
case i1 = <-c1:
print("received ", i1, " from c1\n")
case c2 <- i2:
print("sent ", i2, " to c2\n")

default:
print("no communication\n")
}

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@tapetersen
Copy link

This would be useful much as commented in code using the style of go of waiting for multiple channels.
There is already precedence in exposing this for multiprocessing.connection.Connection objects that have the same issue with early notification of a partial object. Being able to add multiprocessing.Queue as well as Pipe and Connection objects in multiprocessing.wait` would be useful and avoid awkward event handling or polling.

Maybe exposing the reader is too much but either adding a fileno() function that would allow it to be used by most select apis or following the example of multiprocessing.Popenand exposing a sentinel that only guarantees that it is awaitable by multiprocessing.connection.wait() seems reasonable without exposing too much internals.

@tapetersen
Copy link

The same would also be true for the rest of the synchronisation primitives in the multiprocessing library. Right now the only way to do this seems to be to resort to having threads waiting for each non-selectable primitive that can then either set a central Event or post to a Pipe/Connection that can be selected on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
extension-modules C modules in the Modules dir topic-multiprocessing type-feature A feature request or enhancement
Projects
Status: No status
Development

No branches or pull requests

2 participants