Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129748 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 E3A291A00BC for ; Sat, 10 Jan 2026 11:26:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1768044381; bh=RUnHJTespvmpis238L0D7BruZvAJC+BvtrPIV33mlf0=; h=Date:From:To:In-Reply-To:References:Subject:From; b=fBTrI9+Gs4v86L8C94/NxdMGvtcb7Dkys2CvsVZrtHiMV5gK/ItzyeYYCFCmZ0uS+ 7ffRH48VGTVeNyyurcIN2r9KSR38BvdQeb1ZUjxybEBkjR+QkzLMtorJ6L/lFShfDb j9L3A64tZ323+2hCwb64vhVtHNiJRjo7xIBcDKU/obgZzfx3pr7ujGfbeRr513HKIT nvLVAzQPV28s6J7OSrTLIXCZnkzEFH3Dlr70Tp9tVDYl1OGMVnFnurL5KTwSUyuzug JX8Z6GQNaqTpL0c7WlhuHl27u2sRnamitMugVZXRKufslS1tG9BGECNvGeVVUHxBGT SwrPM5cBIIxcw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 30680180056 for ; Sat, 10 Jan 2026 11:26:20 +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 fhigh-b4-smtp.messagingengine.com (fhigh-b4-smtp.messagingengine.com [202.12.124.155]) (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 ; Sat, 10 Jan 2026 11:26:19 +0000 (UTC) Received: from phl-compute-12.internal (phl-compute-12.internal [10.202.2.52]) by mailfhigh.stl.internal (Postfix) with ESMTP id F32B47A0139 for ; Sat, 10 Jan 2026 06:26:13 -0500 (EST) Received: from phl-imap-05 ([10.202.2.95]) by phl-compute-12.internal (MEProxy); Sat, 10 Jan 2026 06:26:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bottled.codes; h=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=1768044373; x=1768130773; bh=r0yiO5ttoX 6PINJbe3th5tnjVBvzO476QGPTkHNxGss=; b=dGSPNJOUTJ+8qNGpjDTr1GUILx p976gpEi8Z2uriXK0q+4P8SYNbFqZCGHcG2mxbImpqOiMN70ZxUp+d5XKWItLJok 6aoWVveniAzBH8EFJ/DCSRZ/gOtAnHe3bW1S/Ad6rmiqWFpHXCsOalkBylamJnMg UMS+CPYze0UOZ6urmMiMTrx5AzLc6khOIg9O5Bqda16/2ODkwVap4vtk316yGCeA gp8852gm6gnJOV4qioAhlWI/GppJ9oY2W7V59IaqHGK9umsFVBY3eMy5CQ32r7kM rMQ9rqz8uI56Db8olWVpSgi1prUxCTCyTNStMx8EF9GL2wv6mSSN5NSM434Q== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=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= 1768044373; x=1768130773; bh=r0yiO5ttoX6PINJbe3th5tnjVBvzO476QGP TkHNxGss=; b=mAd8Fl5Z7z7qOyyCM6T0jYj6VBeU84aadnDK/Trk18vuA+M7BG/ Vf8n6iFPWwjG65kQADbeaJQV4e5TQKeqyr/ONc5b69IPHJCq68yt6ZmTW6jiAaQN +8q5pDujs5TBxA3DDrIMbEPGE/s304Zscqu2p8GWRw+sB2lkbhMLVMgptrwazAv/ 3aEEgDRAokBqnJZbQWvA29DSVM/VqWs1ZPOGC2tyzxqkiIlPh5ckQXB9eAxVSljD sWaljeSh61h/c2G4onRIl9068AWe6AKH3PvL/71BIf/yV9JR+HSHKXnp4dW9SN3h BeEJLk7zQRr0TIy6L1MVPyF7REJTjplcV0Q== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgdduudduheeiucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucenucfjughrpefoggffhffvkfgjfhfutgesrgdtreerre dtjeenucfhrhhomhepfdftohgsucfnrghnuggvrhhsfdcuoehrohgssegsohhtthhlvggu rdgtohguvghsqeenucggtffrrghtthgvrhhnpedtueejtdethfeulefhtdelieduteelff dtudelheffgedtieehhfelieejgfevgeenucevlhhushhtvghrufhiiigvpedtnecurfgr rhgrmhepmhgrihhlfhhrohhmpehrohgssegsohhtthhlvggurdgtohguvghspdhnsggprh gtphhtthhopedupdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehinhhtvghrnhgr lhhssehlihhsthhsrdhphhhprdhnvght X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 824631820054; Sat, 10 Jan 2026 06:26:13 -0500 (EST) 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: A5Jrj2DPXBgg Date: Sat, 10 Jan 2026 12:25:50 +0100 To: internals@lists.php.net Message-ID: <926941aa-f33d-49f0-b23e-32dd3022075e@app.fastmail.com> In-Reply-To: References: Subject: Re: [PHP-DEV] Analogue of Node.js Worker threads? Content-Type: multipart/alternative; boundary=98f8e698beaf44caa87c49db750164b5 From: rob@bottled.codes ("Rob Landers") --98f8e698beaf44caa87c49db750164b5 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Sat, Jan 10, 2026, at 09:19, Pavel Shevaev wrote: > Hi! >=20 > Historically in my company PHP has been used as a CLI tool for project= building purposes. For example for code generation, configs parsing and= converting them into binary blobs, calling dotnet and go tools, etc. In= general it's a cross platform 'make on steroids'.=20 >=20 > We are pretty much happy about it except one particular thing: conveni= ent cross platform multi-threading. And we don't actually need a true mu= lti-threading but rather something similar to Worker threads in Node.js.=20 >=20 > We tried using the AMPHP Parallel package but it wasn't stable enough = for our needs (hangs or emits serialization errors for our workloads). A= nd it also seems to be using a special 'ProcessWrapper.exe' (bundled wit= h a composer package) to overcome some Window specific issues. Due to st= rict anti-virus policies we had to manually add an exception for it... S= o we ended up with some primitive wrappers around platform specific tool= s: for *nix we start background PHP processes with '&', for Windows - us= ing 'powershell.exe Start-Process' for the same purpose. We pass data to= and from these background processes using serialization and temporary f= iles and while it works, well, it's pretty inconvenient and cumbersome. =20 >=20 > Out of curiosity I tried Node.js Worker threads and it just worked as = expected for our sample loads both on *nix and Windows boxes. And there = are some high-level wrappers over Worker threads like Piscina which simp= lify things even further: >=20 > const worker =3D new Piscina({ > filename: path.resolve(__dirname, "worker.js"), > maxThreads: 32, > maxQueue: "auto", > }); >=20 > const results =3D await Promise.all( > files.map((file, idx) =3D> worker.run([file])) > ) > I think PHP could benefit from having the similar 'multi-processing' s= upport in the core. It seems like here's what Node.js does: > 1) Spawns/stops worker threads > 2) Passes serialized input/output between the worker manager and worke= r threads >=20 > Since worker threads are fully isolated you can't directly access thei= r internal data, there are no data races and there's no need for any syn= chronization primitives.=20 >=20 > I guess PHP could do the same even in non ZTS mode? And the aforementi= oned AMPHP could use this built-in Worker threads support without having= to resort to any platform specific hacks providing a nice and clean int= erface. =20 >=20 > -- > Best regards, Pavel Hi Pavel, It isn=E2=80=99t directly possible to share zvals between threads. They = must be copied/serialized, and the context reconstructed. That=E2=80=99s= why the parallel extension works the way it does. There=E2=80=99s also = the phasync library that does this stuff in non-zts PHP, if you=E2=80=99= re interested in a solution you can use today. I don=E2=80=99t know if i= t is used in production, but the maintainer is pretty responsive. There=E2=80=99s some work to make this easier (me refactoring TSM, TrueA= sync), but it probably won=E2=80=99t be a thing until PHP 9.0.=20 =E2=80=94 Rob --98f8e698beaf44caa87c49db750164b5 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable


On Sat, Jan 10, 2026, at 09:19, Pavel Shevaev wrote:
Hi!

Historically in my company PHP has been us= ed as a CLI tool for project building purposes. For example for code gen= eration, configs parsing and converting them into binary blobs, calling = dotnet and go tools, etc. In general it's a cross platform 'make on ster= oids'. 

We are pretty much happy abou= t it except one particular thing: convenient cross platform multi-thread= ing. And we don't actually need a true multi-threading but rather someth= ing similar to Worker threads in Node.js.

We t= ried using the AMPHP Parallel package but it wasn't stable enough for ou= r needs (hangs or emits serialization errors for our workloads= ). And it also seems to be using a special 'ProcessWrapper.exe' (bundled= with a composer package) to overcome some Window specific issues. = Due to strict anti-virus policies we had to manually add an exception fo= r it... So we ended up with some primitive wrappers around platform spec= ific tools: for *nix we start background PHP processes with '&', for= Windows - using 'powershell.exe Start-Process' for the same purpose. We= pass data to and from these background processes using serialization an= d temporary files and while it works, well, it's pretty inconvenien= t and cumbersome.  

Out of curio= sity I tried Node.js Worker threads and it just worked as expected for o= ur sample loads both on *nix and Windows boxes. And there are some high-= level wrappers over Worker threads like Piscina which simplify things ev= en further:

    const worker =3D new = Piscina({
      filename: path.resolve(__dirnam= e, "worker.js"),
      maxThreads: 32,
      maxQueue: "auto",
    });

    const results =3D await Promise.all(=
      files.map((file, idx) =3D> worker.run= ([file]))
    )
I think PHP cou= ld benefit from having the similar 'multi-processing' support in the cor= e. It seems like here's what Node.js does:
1) Spawns/stops wor= ker threads
2) Passes serialized input/output between the work= er manager and worker threads

Since worker thre= ads are fully isolated you can't directly access their internal data, th= ere are no data races and there's no need for any synchronization primit= ives.

I guess PHP could do the same even in no= n ZTS mode? And the aforementioned AMPHP could use this built-in Worker = threads support without having to resort to any platform specific hacks = providing a nice and clean interface.  

--
Best regards, Pavel
<= /blockquote>

Hi Pavel,

It is= n=E2=80=99t directly possible to share zvals between threads. They must = be copied/serialized, and the context reconstructed. That=E2=80=99s why = the parallel extension works the way it does. There=E2=80=99s also the p= hasync library that does this stuff in non-zts PHP, if you=E2=80=99re in= terested in a solution you can use today. I don=E2=80=99t know if it is = used in production, but the maintainer is pretty responsive.
<= br>
There=E2=80=99s some work to make this easier (me refactor= ing TSM, TrueAsync), but it probably won=E2=80=99t be a thing until PHP = 9.0. 

=E2=80=94 Rob --98f8e698beaf44caa87c49db750164b5--