On Fri, Oct 24, 2025, at 09:30, Edmond Dantes wrote: > But it's not a parallelism. > > пт, 24 окт. 2025 г., 09:43 Rob Landers <[email protected]>: >> __ >> >> >> On Fri, Oct 24, 2025, at 08:34, Edmond Dantes wrote: >>> Hello everyone, >>> >>> In the TrueAsync RFC 4 thread, John Bafford raised a question about >>> parallelism. >>> I would like to share my thoughts and highlight this branch of the >>> discussion. >>> >>> # What is parallelism in the context of coroutines? >>> Parallelism for coroutines means the ability to execute a coroutine in >>> one thread or another (but not simultaneously). >>> In this case, the Scheduler not only manages the execution order of >>> coroutines but also decides which thread from the thread pool should >>> be assigned to a coroutine. >>> >>> # What is the problem? >>> >>> If two different coroutines run in separate threads and write to the >>> same memory region — that is, to the same PHP object — it will lead to >>> unpredictable consequences. >>> >>> The issue is that PHP does not control memory access in such cases and >>> effectively allows the programmer to shoot themselves in the head. >>> >>> How can this be solved? >>> >>> ### Object transfer policy >>> >>> The object transfer policy defines how a PHP object can be safely >>> passed to another coroutine. >>> Possible transfer methods: >>> 1. Via parameters >>> 2. Via context >>> 3. Via channels >>> >>> All these methods can be viewed as variations of passing objects >>> through channels (similar to the Erlang model — no direct sharing). >>> >>> The same policy applies to all methods. >>> >>> An interface is defined to guarantee an object’s “thread safety.” For >>> example, if a coroutine receives an object parameter without this >>> interface, an error occurs. >>> >>> In PHP, there are several possible ways to achieve thread safety: >>> 1. **Ownership transfer**, as in C++/Rust — the object leaves the >>> current scope and becomes owned by the coroutine. >>> 2. **Proxy-based access**, using a special constructor that creates a >>> proxy object for access to the real one (similar to actors in Swift). >>> 3. **Shared access** with a built-in mutex. >>> >>> This approach requires minimal changes to the language syntax — in >>> fact, none at all. >>> From a performance standpoint, it is perfectly acceptable for PHP to >>> validate function parameters, so no significant overhead should be >>> expected. >>> >>> The main challenge of parallelism lies in making PHP’s internal state, >>> garbage collector, and memory manager thread-safe. >>> >>> # How does this relate to TrueAsync? >>> >>> At the moment, TrueAsync does not perform additional checks when >>> passing parameters to coroutines. >>> This is a problem — because once PHP introduces concurrency, >>> developers will start freely using references (&reference) and shared >>> objects. >>> >>> When multitasking is later added to coroutines, it will break existing >>> PHP code that has already been written. >>> >>> Therefore, if PHP truly aims to become multithreaded, its memory >>> ownership model must be carefully designed today. >>> >>> --- >>> Best Regards, Ed >>> >> >> I’m not sure this is the place to discuss it, nor the time. But C# is >> cooperative multitasking on top of a VM which is preemptive multitasking. >> This basically allows you to run multithreaded without worrying about >> “shooting yourself in the foot” by accessing the same memory, most of the >> time. In other words, there is plenty of prior art out there and ways to >> solve this problem. It doesn’t mean we need to solve it today. Trying to >> solve a problem that doesn’t currently exist and “might” be a problem later >> is exactly how you end up with overengineered solutions that never actually >> solve the problem. >> >> — Rob
You’re technically right — what you described isn’t parallelism, and it mixes a few distinct concerns: memory safety, ownership, and object transfer, all under the label of “parallelism.” But coroutines are explicitly cooperative. They don’t run in parallel unless a scheduler explicitly assigns them to threads, and we’re a long way from the VM being capable of that. I’m also not sure why we’d even need an “object transfer” system. The entire point of threads is that memory is shared. If you want to pass an object to another thread, you just give it a pointer — full stop. The reason thread-safe extensions need to jump through hoops is TSRM: each thread gets its own VM context and thread-local memory. That’s an engine-level design choice, not a missing userland feature. Opcache, for instance, could theoretically use global memory with traditional locks instead of file locks in ZTS mode, but that’s deep in engine territory — far from anything TrueAsync needs to consider right now. So practically speaking, it’s not worth designing around this yet. The engine would need massive adaptation before userland could safely talk about “parallelism.” What you’re actually raising sounds more like concurrency — specifically, managing mutable state across concurrent coroutines. That’s a valid topic, but concurrency control (locks, ownership semantics, etc.) doesn’t belong in TrueAsync itself. If anything, that would come later as a separate layer or RFC once the concurrency model stabilizes. It really should just be listed as Future Scope on that RFC and dealt with if or when the RFC lands. — Rob
