Hi,
I'm generally in favour of PEP 554, but I don't think it is ready to be
accepted in its current form.
My main objection is that without per-subinterpeter GILs (SILs?) PEP 554
provides no value over threading or multi-processing.
Multi-processing provides true parallelism and threads provide shared
memory concurrency.
If per-subinterpeter GILs are possible then, and only then,
sub-interpreters will provide true parallelism and (limited) shared
memory concurrency.
The problem is that we don't know whether we can implement
per-subinterpeter GILs without too large a negative performance impact.
I think we can, but we can't say so for certain.
So, IMO, we should not accept PEP 554 until we know for sure that
per-subinterpeter GILs can be implemented efficiently.
Detailed critique
-----------------
I don't see how `list_all()` can be both safe and accurate. The Java
equivalent makes no guarantees of accuracy.
Attempting to lock the list is likely to lead to deadlock and not
locking it will lead to races; potentially dangerous ones.
I think it would be best to drop this.
`list_all_channels()`. See `list_all()` above.
`.destroy()` is either misleading or unsafe.
What does this do?
>>> is.destroy()
>>> is.run()
If `run()` raises an exception then the interpreter must exist. Rename
to `close()` perhaps?
`Channel.interpreters` see `list_all()` and `list_all_channels()` above.
How does `is_shareable()` work? Are you proposing some mechanism to
transfer an object from one sub-interpreter to another? How would that
work? If objects are not shared but serialized, why not use marshal or
pickle instead of inventing a third serialization protocol?
It would be clearer if channels only dealt with simple, contiguous
binary data. As it stands the PEP doesn't state what form the received
object will take.
Once channels supporting the transfer of bytes objects work, then it is
simple to pass more complex objects using pickle or marshal.
Channels need a more detailed description of their lifespan. Ideally a
state machine.
For example:
How does an interpreter detach from the receiving end of a channel that
is never empty?
What happens if an interpreter deletes the last reference to a non-empty
channel? On the receiving end, or on the sending end?
Isn't the lack of buffering in channels a recipe for deadlocks?
What is the mechanism for reliably copying exceptions from one
sub-interpreter to another in the `run()` method? If `run()` can raise
an exception, why not let it return values?
Cheers,
Mark.
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at
https://mail.python.org/archives/list/python-dev@python.org/message/ZSE2G37E24YYLNMQKOQSBM46F7KLAOZF/
Code of Conduct: http://python.org/psf/codeofconduct/