Rumah >pembangunan bahagian belakang >PHP8 >PHP8.1 ciri baharu menjelaskan: Serat dengan sebutir garam

PHP8.1 ciri baharu menjelaskan: Serat dengan sebutir garam

藏色散人
藏色散人asal
2021-11-10 15:25:275062semak imbas

Artikel ini ialah terjemahan, alamat asal: https://stitcher.io/blog/fibers-with-a-grain-of-salt

Fibers with sebutir garam

Jadi saya akan menulis catatan blog yang mendalam tentang menggunakan Fibers dalam PHP 8.1. Kami akan menerangkannya dari bawah ke atas, bermula dengan contoh asas. Ideanya adalah untuk menghantar permintaan HTTP tak segerak dan memprosesnya secara selari menggunakan gentian.

Tetapi bermain-main dengan mereka, saya mengetahui bahawa RFC tidak bergurau apabila ia berkata "API Fiber tidak boleh digunakan secara langsung dalam kod peringkat aplikasi. Fibers menyediakan API kawalan aliran peringkat rendah asas untuk mencipta abstraksi peringkat lebih tinggi yang kemudiannya digunakan dalam kod aplikasi."

Jadi, daripada pergi ke laluan ini dan merumitkan perkara yang terlalu rumit, kami akan membincangkan konsep gentian, sebab ia hampir tidak boleh digunakan dalam kod aplikasi dan bagaimana sebenarnya anda boleh menggunakan PHP tak segerak.

Pertama, sedikit teori.

Andaikan anda ingin menghantar tiga permintaan HTTP dan memproses hasil gabungannya. Cara segerak untuk melakukan ini adalah dengan menghantar yang pertama, tunggu respons, kemudian hantar yang kedua, tunggu, dan seterusnya.

Mari kita gunakan gambar rajah yang paling mudah untuk mewakili aliran program sedemikian. Anda perlu membaca carta ini dari atas ke bawah, dengan masa berjalan lebih jauh ke bawah. Setiap warna mewakili permintaan HTTP. Bahagian berwarna bagi setiap permintaan mewakili kod PHP sebenar yang sedang berjalan, CPU pada pelayan anda melakukan kerja, dan blok lutsinar mewakili masa menunggu: permintaan itu perlu dihantar melalui rangkaian, dan pelayan lain perlu memprosesnya dan menghantar ia kembali.

PHP8.1 ciri baharu menjelaskan: Serat dengan sebutir garam

Ini ialah proses pelaksanaan segerak: hantar, tunggu, proses, ulang.

Dalam dunia pemprosesan selari, kami menghantar permintaan tetapi jangan tunggu. Kemudian kami menghantar permintaan seterusnya, dan kemudian yang lain. Hanya selepas itu kami menunggu semua permintaan. Semasa menunggu, kami menyemak secara berkala untuk melihat sama ada salah satu permintaan kami telah selesai. Jika ini berlaku, kami boleh menanganinya dengan segera.

PHP8.1 ciri baharu menjelaskan: Serat dengan sebutir garam

Anda boleh lihat bagaimana pendekatan ini mengurangkan masa pelaksanaan kerana kami menggunakan masa menunggu dengan lebih optimum.

Fibers ialah mekanisme baharu dalam PHP 8.1 yang membolehkan anda mengurus laluan pelaksanaan selari ini dengan lebih cekap. Hasil sudah boleh didapati menggunakan penjana dan , tetapi gentian merupakan peningkatan yang ketara kerana ia direka khusus untuk kes penggunaan ini.

Anda akan membuat gentian untuk setiap permintaan dan menjeda gentian selepas permintaan dihantar. Selepas mencipta ketiga-tiga gentian, anda akan melingkarkannya dan memulihkannya satu demi satu. Dengan melakukan ini, gentian menyemak sama ada permintaan telah selesai dan menjeda sekali lagi jika tidak, jika tidak, ia boleh memproses respons dan akhirnya selesai.

Anda lihat, gentian ialah mekanisme untuk memulakan, menjeda dan menyambung semula bahagian terpencil aliran pelaksanaan program. Gentian juga dikenali sebagai "benang hijau": benang yang sebenarnya wujud dalam proses yang sama. Benang ini tidak diuruskan oleh sistem pengendalian, tetapi oleh masa jalan - dalam kes kami, masa jalan PHP. Ia adalah cara kos efektif untuk menguruskan beberapa bentuk pengaturcaraan selari.

Tetapi ambil perhatian bahawa mereka tidak menambah apa-apa yang benar-benar tak segerak: semua gentian berada dalam proses PHP yang sama dan hanya satu gentian boleh dijalankan pada satu-satu masa. Ini adalah proses utama yang melingkari mereka dan memeriksanya semasa menunggu, gelung ini sering dipanggil "gelung peristiwa".

Bahagian yang sukar tentang keselarian bukanlah bagaimana anda menggelungkan gentian atau penjana, atau apa sahaja mekanisme yang anda mahu gunakan; ia adalah tentang dapat memulakan operasi, menyerahkannya kepada perkhidmatan luaran dan hanya Semak keputusan apabila anda mahu dengan cara yang tidak menyekat.

Lihat, dalam contoh sebelumnya, kami menganggap kami hanya boleh menghantar permintaan dan kemudian menyemak responsnya apabila kami mahu, tetapi itu sebenarnya tidak semudah yang disangkakan.

Betul: kebanyakan fungsi PHP yang mengendalikan I/O tidak mempunyai fungsi tidak menyekat terbina dalam ini. Malah, hanya beberapa fungsi yang melakukannya, dan menggunakannya adalah menyusahkan.

Terdapat contoh soket yang boleh ditetapkan kepada tidak menyekat, seperti ini:

[$read, $write] = stream_socket_pair(
    STREAM_PF_UNIX,
    STREAM_SOCK_STREAM,
    STREAM_IPPROTO_IP
);
 
stream_set_blocking($read, false);
stream_set_blocking($write, false);

Dengan menggunakan stream_socket_pair(), dua soket dicipta yang boleh digunakan untuk dwiarah komunikasi mengambil kata-kata. Seperti yang anda lihat, ia boleh diakses menggunakan stream_set_blocking().

Andaikan kami ingin melaksanakan contoh kami, menghantar tiga permintaan. Kita boleh melakukan ini menggunakan soket, tetapi kita perlu melaksanakan protokol HTTP sendiri di atasnya. Itulah yang dilakukan oleh nox7, pengguna yang berkongsi bukti kecil konsep di Reddit untuk menunjukkan cara menghantar permintaan HTTP GET menggunakan gentian dan soket. Adakah anda benar-benar mahu melakukan ini dalam kod aplikasi anda?

Bagi saya sekurang-kurangnya, jawapannya ialah "tidak". Itulah yang diberi amaran oleh RFC; Sebaliknya, kami menggalakkan menggunakan salah satu rangka kerja tak segerak sedia ada: Amp atau ReactPHP.

Sebagai contoh, menggunakan ReactPHP, kita boleh menulis:

$loop = React\EventLoop\Factory::create();
$browser = new Clue\React\Buzz\Browser($loop);
$promises = [
    $browser->get('https://example.com/1'),
    $browser->get('https://example.com/2'),
    $browser->get('https://example.com/3'),
];
$responses = Block\awaitAll($promises, $loop);

与手动创建套接字连接相比,这是一个更好的示例。这就是 RFC 的意思:应用程序开发人员不需要担心纤程,它是 Amp 或 ReactPHP 等框架的实现细节。

不过,这给我们带来了一个问题:与我们已经可以用发电机做的事情相比,纤维有什么好处?RFC 是这样解释的:

与无堆栈生成器不同,每个 Fiber 都有自己的调用堆栈,允许它们在深度嵌套的函数调用中暂停。声明中断点的函数(即调用 Fiber::suspend())不需要更改其返回类型,这与使用 yield 的函数必须返回 Generator 实例不同。

Fiber 可以在任何函数调用中挂起,包括那些从 PHP VM 内部调用的函数,例如提供给 array_map 的函数或迭代器对象上的 foreach 调用的方法。

很明显,纤程在语法和灵活性方面都有显着的改进。但与 Go 及其“ goroutines ”相比,它们还不算什么。

要使异步 PHP 在没有框架开销的情况下成为主流,仍然缺少许多功能,而 Fiber 是朝着正确方向迈出的良好一步,但我们还没有做到这一点。

所以就是这样。如果您不是 Amp、ReactPHP 或较小的异步 PHP 框架的维护者,那么实际上没有什么可说的。也许更多的框架或库将开始合并它们?

同时,还有Swoole——一个 PHP 扩展,它实际上将几个核心功能修改为非阻塞。Swoole 本身是一个中文项目,在涉及英语时通常没有很好的文档记录,但最近 Laravel宣布与它进行第一方集成。也许这是将 PHP 推向更异步模型的更好策略:可选择将 Swoole 或其他扩展与 Laravel 和 Symfony 等框架集成?

Atas ialah kandungan terperinci PHP8.1 ciri baharu menjelaskan: Serat dengan sebutir garam. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn