Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128946 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id 9923E1A00BC for ; Fri, 24 Oct 2025 09:20:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1761297626; bh=ps6FD2x5ZQgRXaTdKUr6i9z8TV8goTQa4KVtn8Hoxu4=; h=Date:From:To:Cc:In-Reply-To:References:Subject:From; b=Kr9iPBJ3uZBVYLFNB6yudC3mKnm9H+yD2C7Ish/6FIRAwGKTeLlw3jPTWgrmv9qrK t7xePh0XRSxJNpN/NS60wO5f86NVSDrBiFeYSTjJgJt6coEGh++CF7ZDU+fXaa91B7 wXUv+lSoX0Lf+iQEFTgm1rUw8V0L4Lpei6Sp7mAZZIWUpwkVTHPOj2GtnxzMB0sA8J f1PFaCdCRR3pzvBiwzVSm43OwSCmh4gNq4BUpV5PMuxpNu30niptYIC47sm35cJi8i t3qKsNbwvSI4f7yg3HRko2IAynW3S3M9N8a/UJqdbA+FBAcwdxlxrjz486mrKYBz7z 1WOh74kRnE4Tg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 01AFE180087 for ; Fri, 24 Oct 2025 09:20:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from fout-b8-smtp.messagingengine.com (fout-b8-smtp.messagingengine.com [202.12.124.151]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Fri, 24 Oct 2025 09:20:24 +0000 (UTC) Received: from phl-compute-05.internal (phl-compute-05.internal [10.202.2.45]) by mailfout.stl.internal (Postfix) with ESMTP id 245A71D001AA; Fri, 24 Oct 2025 05:20:19 -0400 (EDT) Received: from phl-imap-05 ([10.202.2.95]) by phl-compute-05.internal (MEProxy); Fri, 24 Oct 2025 05:20:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bottled.codes; h=cc:cc:content-type:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm3; t=1761297619; x= 1761384019; bh=ps6FD2x5ZQgRXaTdKUr6i9z8TV8goTQa4KVtn8Hoxu4=; b=R f4/t8gjnuyVXps2sKt9Dxanaf2ibBiwhiojHAEenpJl6fiH7s11468QJCW+c8h7m MCyx6g6EiuJTPx6W78GRrrbrSMKh99OLtljXh60RyrShJpFTbmj5rcWEImJMH3Hc /9kGFwPTj3ufusvH2hzXicjJmtjJcTPfwfKeHKCZP41gpd61aotp6XJ+MSyhPnbR e+EJUaDBg4hwQgo/aLQN15YJyK/n2vafM11koJRHOFJl+Phv454ERlMOf/hHUqQZ vRU4VmP3rpF8I+4i440EDN4cEVmUiLfWPL0InhhXQDiUoOhzKSpQTjIRD/B6Jatw Rm6XZnk7tFs8QegEa/2qA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t= 1761297619; x=1761384019; bh=ps6FD2x5ZQgRXaTdKUr6i9z8TV8goTQa4KV tn8Hoxu4=; b=Xt+BLE2tV8nd7OrsanLq4sJyf8xbK//MaXnS+oF3pEkzuFFFRU/ K9HUxz3lDmBqKaSzFh3KiQIfMsOF41Y/fPcIeaw59ud+gVg+mycdiUjncZ/YH0bF grjIikZDYhTLZzsEVDH5D5FWabfe1QABusR08tUuoL+xqWgMB16+EcXJSzeFHNvZ VPwFzDs3JhMDk6B1VhudUtKIgIcUYc9ZJ0qmZNywPIUoDOGs6yru9A0UWnepEWCy cxcEsk6yltZyKPw2uIhhKmGcJ61CeTBf5CzrjfZgoCBZ5zOZBUhtsjK/giqZsdZx 5TVPgKe8gG0eLfP2LfL/HBV5xWdRPm2e6CQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdeggddugeekleeiucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujf gurhepofggfffhvfevkfgjfhfutgesrgdtreerredtjeenucfhrhhomhepfdftohgsucfn rghnuggvrhhsfdcuoehrohgssegsohhtthhlvggurdgtohguvghsqeenucggtffrrghtth gvrhhnpeeiueethedvvdefjefhgfeiheelheehtdfhfeekjefflefgvedvkeduteejjedt tdenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehroh gssegsohhtthhlvggurdgtohguvghspdhnsggprhgtphhtthhopedvpdhmohguvgepshhm thhpohhuthdprhgtphhtthhopegvughmohhnugdrhhhtsehgmhgrihhlrdgtohhmpdhrtg hpthhtohepihhnthgvrhhnrghlsheslhhishhtshdrphhhphdrnhgvth X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 8978D182007A; Fri, 24 Oct 2025 05:20:18 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 X-ThreadId: Ao23bsqP5RK3 Date: Fri, 24 Oct 2025 11:19:57 +0200 To: "Edmond Dantes" Cc: "php internals" Message-ID: <0c852933-607a-4d50-94a8-641a3318f3c9@app.fastmail.com> In-Reply-To: References: Subject: [PHP-DEV] Re: PHP and parallelism Content-Type: multipart/alternative; boundary=4a9e9630861745ac932ce018044abccf From: rob@bottled.codes ("Rob Landers") --4a9e9630861745ac932ce018044abccf Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Fri, Oct 24, 2025, at 09:30, Edmond Dantes wrote: > But it's not a parallelism.=20 >=20 > =D0=BF=D1=82, 24 =D0=BE=D0=BA=D1=82. 2025=E2=80=AF=D0=B3., 09:43 Rob L= anders : >> __ >>=20 >>=20 >> On Fri, Oct 24, 2025, at 08:34, Edmond Dantes wrote: >>> Hello everyone, >>>=20 >>> 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 d= iscussion. >>>=20 >>> # 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. >>>=20 >>> # What is the problem? >>>=20 >>> If two different coroutines run in separate threads and write to the >>> same memory region =E2=80=94 that is, to the same PHP object =E2=80=94= it will lead to >>> unpredictable consequences. >>>=20 >>> The issue is that PHP does not control memory access in such cases a= nd >>> effectively allows the programmer to shoot themselves in the head. >>>=20 >>> How can this be solved? >>>=20 >>> ### Object transfer policy >>>=20 >>> 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 >>>=20 >>> All these methods can be viewed as variations of passing objects >>> through channels (similar to the Erlang model =E2=80=94 no direct sh= aring). >>>=20 >>> The same policy applies to all methods. >>>=20 >>> An interface is defined to guarantee an object=E2=80=99s =E2=80=9Cth= read safety.=E2=80=9D For >>> example, if a coroutine receives an object parameter without this >>> interface, an error occurs. >>>=20 >>> In PHP, there are several possible ways to achieve thread safety: >>> 1. **Ownership transfer**, as in C++/Rust =E2=80=94 the object leave= s 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. >>>=20 >>> This approach requires minimal changes to the language syntax =E2=80= =94 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. >>>=20 >>> The main challenge of parallelism lies in making PHP=E2=80=99s inter= nal state, >>> garbage collector, and memory manager thread-safe. >>>=20 >>> # How does this relate to TrueAsync? >>>=20 >>> At the moment, TrueAsync does not perform additional checks when >>> passing parameters to coroutines. >>> This is a problem =E2=80=94 because once PHP introduces concurrency, >>> developers will start freely using references (&reference) and shared >>> objects. >>>=20 >>> When multitasking is later added to coroutines, it will break existi= ng >>> PHP code that has already been written. >>>=20 >>> Therefore, if PHP truly aims to become multithreaded, its memory >>> ownership model must be carefully designed today. >>>=20 >>> --- >>> Best Regards, Ed >>>=20 >>=20 >> I=E2=80=99m not sure this is the place to discuss it, nor the time. B= ut C# is cooperative multitasking on top of a VM which is preemptive mul= titasking. This basically allows you to run multithreaded without worryi= ng about =E2=80=9Cshooting yourself in the foot=E2=80=9D by accessing th= e same memory, most of the time. In other words, there is plenty of prio= r art out there and ways to solve this problem. It doesn=E2=80=99t mean = we need to solve it today. Trying to solve a problem that doesn=E2=80=99= t currently exist and =E2=80=9Cmight=E2=80=9D be a problem later is exac= tly how you end up with overengineered solutions that never actually sol= ve the problem.=20 >>=20 >> =E2=80=94 Rob You=E2=80=99re technically right =E2=80=94 what you described isn=E2=80=99= t parallelism, and it mixes a few distinct concerns: memory safety, owne= rship, and object transfer, all under the label of =E2=80=9Cparallelism.= =E2=80=9D But coroutines are explicitly cooperative. They don=E2=80=99t = run in parallel unless a scheduler explicitly assigns them to threads, a= nd we=E2=80=99re a long way from the VM being capable of that. I=E2=80=99m also not sure why we=E2=80=99d even need an =E2=80=9Cobject = transfer=E2=80=9D system. The entire point of threads is that memory is = shared. If you want to pass an object to another thread, you just give i= t a pointer =E2=80=94 full stop. The reason thread-safe extensions need = to jump through hoops is TSRM: each thread gets its own VM context and t= hread-local memory. That=E2=80=99s 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=E2=80=99s deep in engine territory =E2=80=94 far from anything= TrueAsync needs to consider right now. So practically speaking, it=E2=80=99s not worth designing around this ye= t. The engine would need massive adaptation before userland could safely= talk about =E2=80=9Cparallelism.=E2=80=9D What you=E2=80=99re actually raising sounds more like concurrency =E2=80= =94 specifically, managing mutable state across concurrent coroutines. T= hat=E2=80=99s a valid topic, but concurrency control (locks, ownership s= emantics, etc.) doesn=E2=80=99t belong in TrueAsync itself. If anything,= that would come later as a separate layer or RFC once the concurrency m= odel stabilizes. It really should just be listed as Future Scope on that= RFC and dealt with if or when the RFC lands. =E2=80=94 Rob --4a9e9630861745ac932ce018044abccf Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable


On Fri, Oct 24, 2025, at 09:30, Edmond Dantes wrote:
But= it's not a parallelism. 

=D0=BF=D1=82, 24 =D0=BE=D0=BA=D1=82. 2025=E2=80=AF=D0=B3., 09:43 Rob = Landers <rob@bottled.codes>:

=

On Fri, Oct 24, 2025, at 08:34, Edmond Dan= tes 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 t= he discussion.

# What is parallelism in the con= text of coroutines?
Parallelism for coroutines means the abili= ty to execute a coroutine in
one thread or another (but not si= multaneously).
In this case, the Scheduler not only manages th= e execution order of
coroutines but also decides which thread = from the thread pool should
be assigned to a coroutine.
<= div>
# What is the problem?

If tw= o different coroutines run in separate threads and write to the
same memory region =E2=80=94 that is, to the same PHP object =E2=80=94= it will lead to
unpredictable consequences.

The issue is that PHP does not control memory access in such cas= es and
effectively allows the programmer to shoot themselves i= n the head.

How can this be solved?
<= br>
### Object transfer policy

The ob= ject transfer policy defines how a PHP object can be safely
pa= ssed 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= =E2=80=94 no direct sharing).

The same policy = applies to all methods.

An interface is defined= to guarantee an object=E2=80=99s =E2=80=9Cthread safety.=E2=80=9D For
example, if a coroutine receives an object parameter without th= is
interface, an error occurs.

In PHP= , there are several possible ways to achieve thread safety:
1.= **Ownership transfer**, as in C++/Rust =E2=80=94 the object leaves the<= /div>
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 Swif= t).
3. **Shared access** with a built-in mutex.

=
This approach requires minimal changes to the language syntax= =E2=80=94 in
fact, none at all.
From a performance = standpoint, it is perfectly acceptable for PHP to
validate fun= ction parameters, so no significant overhead should be
expecte= d.

The main challenge of parallelism lies in ma= king PHP=E2=80=99s internal state,
garbage collector, and memo= ry manager thread-safe.

# How does this relate = to TrueAsync?

At the moment, TrueAsync does not= perform additional checks when
passing parameters to coroutin= es.
This is a problem =E2=80=94 because once PHP introduces co= ncurrency,
developers will start freely using references (&= ;reference) and shared
objects.

When = multitasking is later added to coroutines, it will break existing
<= div>PHP code that has already been written.

The= refore, if PHP truly aims to become multithreaded, its memory
= ownership model must be carefully designed today.

---
Best Regards, Ed

=
I=E2=80=99m not sure this is the place to discuss it, nor= the time. But C# is cooperative multitasking on top of a VM which is pr= eemptive multitasking. This basically allows you to run multithreaded wi= thout worrying about =E2=80=9Cshooting yourself in the foot=E2=80=9D by = accessing the same memory, most of the time. In other words, there is pl= enty of prior art out there and ways to solve this problem. It doesn=E2=80= =99t mean we need to solve it today. Trying to solve a problem that does= n=E2=80=99t currently exist and =E2=80=9Cmight=E2=80=9D be a problem lat= er is exactly how you end up with overengineered solutions that never ac= tually solve the problem. 

=E2=80=94 Rob

You=E2=80=99re technically right =E2=80= =94 what you described isn=E2=80=99t parallelism, and it mixes a few dis= tinct concerns: memory safety, ownership, and object transfer, all under= the label of =E2=80=9Cparallelism.=E2=80=9D But coroutines are explicit= ly cooperative. They don=E2=80=99t run in parallel unless a scheduler ex= plicitly assigns them to threads, and we=E2=80=99re a long way from the = VM being capable of that.

I=E2=80=99m also = not sure why we=E2=80=99d even need an =E2=80=9Cobject transfer=E2=80=9D= system. The entire point of threads is that memory is shared. If you wa= nt to pass an object to another thread, you just give it a pointer =E2=80= =94 full stop. The reason thread-safe extensions need to jump through ho= ops is TSRM: each thread gets its own VM context and thread-local memory= . That=E2=80=99s an engine-level design choice, not a missing userland f= eature. Opcache, for instance, could theoretically use global memory wit= h traditional locks instead of file locks in ZTS mode, but that=E2=80=99= s deep in engine territory =E2=80=94 far from anything TrueAsync needs t= o consider right now.

So practically speaki= ng, it=E2=80=99s not worth designing around this yet. The engine would n= eed massive adaptation before userland could safely talk about =E2=80=9C= parallelism.=E2=80=9D

What you=E2=80=99re a= ctually raising sounds more like concurrency =E2=80=94 specifically, man= aging mutable state across concurrent coroutines. That=E2=80=99s a valid= topic, but concurrency control (locks, ownership semantics, etc.) doesn= =E2=80=99t belong in TrueAsync itself. If anything, that would come late= r as a separate layer or RFC once the concurrency model stabilizes. It r= eally should just be listed as Future Scope on that RFC and dealt with i= f or when the RFC lands.

=E2= =80=94 Rob
--4a9e9630861745ac932ce018044abccf--