Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Pemahaman menyeluruh tentang pemprosesan isyarat proses PHP dalam satu artikel

Pemahaman menyeluruh tentang pemprosesan isyarat proses PHP dalam satu artikel

藏色散人
藏色散人ke hadapan
2023-04-01 07:30:032006semak imbas

Artikel ini membawakan anda pengetahuan yang berkaitan tentang PHP, yang terutamanya memperkenalkan pemprosesan isyarat proses PHP secara terperinci Rakan-rakan yang berminat boleh melihatnya bersama-sama.

Pemahaman menyeluruh tentang pemprosesan isyarat proses PHP dalam satu artikel

Latar Belakang

Bos mengaturkannya untuk saya berdua minggu lalu saya memulakan tugas dan menulis pakej yang mendengar isyarat. Kerana projek syarikat kami berjalan dalam bekas, setiap kali mereka pergi ke dalam talian, mereka perlu membungkus semula imej dan kemudian memulakannya. Sebelum pembungkusan semula, Dokcer akan menghantar isyarat terlebih dahulu kepada bekas, kemudian tunggu tempoh tamat masa (default 10s), dan kemudian menghantar isyarat SIGKILL untuk menamatkan kontena

Sekarang terdapat situasi di mana terdapat pemastautin proses dalam bekas , tugas proses pemastautin ini adalah untuk terus menggunakan mesej dalam baris gilir. Katakan anda ingin pergi ke dalam talian sekarang dan anda perlu menutup bekas Docker menghantar isyarat kepada proses pemastautin yang berjalan dalam bekas, memberitahu bahawa saya akan menutup anda dalam masa 10 saat proses baru sahaja dikeluarkan daripada baris gilir Untuk mesej, proses telah dimatikan sebelum logik seterusnya dilaksanakan dalam masa 1 saat Pada masa ini, mesej hilang dan data kotor mungkin dihasilkan

Di atas adalah latar belakang tugas ini, yang diperlukan Tentukan cara untuk meneruskan dengan memantau isyarat. Untuk situasi di atas, apabila proses pemastautin menerima isyarat penutupan yang dihantar oleh Docker, proses tersebut boleh disekat dan tidur sehingga kontena dimatikan. OK, selepas menjelaskan latar belakang, mari kita perkenalkan isyarat dalam PHP (saya akan menyusun artikel tentang cara menulis pakej ini kemudian, dan menerbitkan pakej itu ke https://packagist.org/ untuk kegunaan rakan-rakan yang memerlukannya) [ Kajian yang disyorkan :Tutorial video PHP]

1. Apakah isyarat dalam sistem pengendalian Linux

1. Pengenalan ringkas kepada isyarat

Isyarat ialah mekanisme pemberitahuan untuk proses apabila peristiwa berlaku, kadangkala juga dipanggil perisian mengganggu . Sesuatu proses boleh menghantar isyarat kepada proses lain Contohnya, apabila proses anak tamat, ia akan menghantar SIGCHLD (Isyarat No. 17) kepada proses induk untuk memberitahu proses induk, jadi kadangkala isyarat juga digunakan sebagai antara- mekanisme komunikasi proses.

Dalam sistem Linux, kami biasanya menggunakan kill -9 XXPID untuk menamatkan proses Sebenarnya, intipati arahan ini adalah untuk menghantar SIGKILL (Isyarat No. 9) untuk proses latar depan biasanya menggunakan Ctrl+c Kekunci pintasan digunakan untuk menamatkan larian Intipati kekunci pintasan adalah untuk menghantar SIGINT (Isyarat No. 2) ke proses semasa, dan kelakuan lalai proses menerima isyarat ini adalah untuk menamatkan proses. berjalan

2. Isyarat yang biasa digunakan

Isyarat di bawah ini boleh dilihat menggunakan perintah kill -l Berikut ialah beberapa isyarat penting dan biasa digunakan:

信号名 信号值 信号类型 信号描述
SIGHUP 1 终止进程(终端线路挂断) 本信号在用户终端连接(正常或非正常、结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端不再关联
SIGQUIT 2 终止进程(中断进程) 程序终止(interrupt、信号, 在用户键入INTR字符(通常是Ctrl-C、时发出
SIGQUIT 3 建立CORE文件终止进程,并且生成CORE文件 进程,并且生成CORE文件 SIGQUIT 和SIGINT类似, 但由QUIT字符(通常是Ctrl-、来控制. 进程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信 号
SIGFPE 8 建立CORE文件(浮点异常) SIGFPE 在发生致命的算术运算错误时发出. 不仅包括浮点运算错误, 还包括溢 出及除数为0等其它所有的算术的错误
SIGKILL 9 终止进程(杀死进程) SIGKILL 用来立即结束程序的运行. 本信号不能被阻塞, 处理和忽略
SIGSEGV 11
SIGSEGV 试图访问未分配给自己的内存, 或试图往没有写权限的内存地址写数据
SIGALRM 14 终止进程(计时器到时) SIGALRM 时钟定时信号, 计算的是实际的时间或时钟时间. alarm函数使用该信号
SIGTERM 15 终止进程(软件终止信号) SIGTERM 程序结束(terminate、信号, 与SIGKILL不同的是该信号可以被阻塞和处理. 通常用来要求程序自己正常退出. shell命令kill缺省产生这个信号
SIGCHLD 17 忽略信号(当子进程停止或退出时通知父进程) SIGCHLD 子进程结束时, 父进程会收到这个信号
SIGVTALRM 26 终止进程(虚拟计时器到时) SIGVTALRM 虚拟时钟信号. 类似于SIGALRM, 但是计算的是该进程占用的CPU时间
SIGIO 29 忽略信号(描述符上可以进行I/O) SIGIO 文件描述符准备就绪, 可以开始进行输入/输出操作

2. Fungsi berkaitan pemprosesan isyarat dalam PHP

sambungan pcntl PHP dan posix Pelanjutan memberikan kami beberapa kaedah untuk isyarat pengendalian (jika anda ingin menggunakan fungsi ini, anda perlu memasang sambungan ini terlebih dahulu)

Berikut ialah pengenalan terperinci kepada beberapa kaedah yang saya gunakan dalam tugasan ini: Struktur isytihar digunakan untuk menetapkan arahan pelaksanaan sekeping kod. Sintaks pengisytiharan adalah serupa dengan struktur kawalan aliran lain Bahagian arahan

membolehkan anda menetapkan gelagat segmen kod isytihar. Pada masa ini, hanya dua arahan yang dikenali: tanda dan pengekodan. Bahagian pernyataan dalam segmen kod isytihar akan dilaksanakan - cara ia dilaksanakan dan kesan sampingan yang berlaku semasa pelaksanaan bergantung pada arahan yang ditetapkan dalam arahan Ticks

Tandakan ( Kitaran jam) ialah peristiwa yang berlaku setiap kali jurubahasa melaksanakan N jadual waktu
declare (directive)
    statement
penyataan peringkat rendah

dalam segmen kod isytiharkan Nilai N ditentukan dengan ticks=N dalam bahagian arahan isytihar. Tidak semua kenyataan boleh ditetapkan masa. Biasanya ungkapan bersyarat dan

ungkapan parameter

tidak mengikut masa. Peristiwa yang muncul dalam setiap tanda ditentukan oleh register_tick_function(). Untuk maklumat lebih terperinci, sila lihat dokumentasi rasmi: https://www.php.net/manual/zh/control-structures.declare.php

pcntl_signal

pcntl_signal, pasang pemproses isyarat
<?php
declare(ticks=1);//每执行一条时,触发register_tick_function()注册的函数
$a=1;//在注册之前,不算
function test(){//定义一个函数
    echo "执行\n";
}
register_tick_function(&#39;test&#39;);//该条注册函数会被当成低级语句被执行
for($i=0;$i<=2;$i++){//for算一条低级语句
    $i=$i;//赋值算一条
}
输出:六个“执行”

Fungsi pcntl_signal() memasang pemproses isyarat baharu untuk isyarat yang ditentukan oleh signo

posix_kill

pcntl_signal ( int $signo , callback $handler [, bool $restart_syscalls = true ] ) : bool

posix_kill, menghantar isyarat kepada proses
declare(ticks = 1);
pcntl_signal(SIGINT,function(){
    echo "你按了Ctrl+C".PHP_EOL;
});
while(1){
    sleep(1);//死循环运行低级语句
}
输出:当按Ctrl+C之后,会输出“你按了Ctrl+C”

Yang pertama satu Parameter ialah ID proses, dan parameter kedua ialah isyarat yang anda mahu hantar

pcntl_signal_dispatch , hubungi pemproses menunggu isyarat

posix_kill ( int $pid , int $sig ) : bool
Fungsi pcntl_signal_dispatch() memanggil setiap pemproses menunggu isyarat yang dipasang melalui pcntl_signal()

a.php
<?php
declare(ticks = 1);
echo getmypid();//获取当前进程id
pcntl_signal(SIGINT,function(){
    echo "你给我发了SIGINT信号";
});
while(1){
    sleep(1);
}

b.php
<?php
posix_kill(执行1.php时输出的进程id, SIGINT);

pcntl_async_signals()Pemprosesan isyarat tak segerak, digunakan untuk membolehkan pemprosesan isyarat tak segerak tanpa kutu (yang akan membawa banyak overhed tambahan). (PHP>=7.1)

pcntl_signal_dispatch ( void ) : bool

3 Cara mengendalikan semaphore dalam PHP
<?php
echo "安装信号处理器...\n";
pcntl_signal(SIGHUP,  function($signo) {
     echo "信号处理器被调用\n";
});
echo "为自己生成SIGHUP信号...\n";
posix_kill(posix_getpid(), SIGHUP);
echo "分发...\n";
pcntl_signal_dispatch();
echo "完成\n";
?>

输出:
安装信号处理器...
为自己生成SIGHUP信号...
分发...
信号处理器被调用
完成

Kami di sini Kami tahu bahawa kami boleh memantau isyarat melalui gabungan declare(ticks=1) dan pcntl_signal Iaitu, setiap pernyataan PHP peringkat rendah akan menyemak sama ada terdapat isyarat yang tidak diproses dalam proses semasa. Prinsip pelaksanaan pcntl_signal ialah terlebih dahulu menambah isyarat pada baris gilir selepas mencetuskan isyarat. Kemudian semak secara berterusan sama ada terdapat isyarat dalam fungsi panggil balik kutu PHP Jika terdapat isyarat, jalankan fungsi panggil balik yang dinyatakan dalam PHP. Jika tidak, lompat keluar dari fungsi.

Selepas PHP5.3, terdapat fungsi pcntl_signal_dispatch. Pada masa ini, anda tidak perlu lagi mengisytiharkan Anda hanya perlu menambah fungsi dalam gelung untuk memanggil isyarat dan lulus:

<?php
pcntl_async_signals(true); // turn on async signals

pcntl_signal(SIGHUP,  function($sig) {
    echo "SIGHUP\n";
});

posix_kill(posix_getpid(), SIGHUP);

输出:
SIGHUP

Semua orang tahu bahawa ticks=1 PHP bermakna fungsi ini akan menjadi. dipanggil semula setiap kali 1 baris kod PHP dilaksanakan. Malah, tiada isyarat dihasilkan pada kebanyakan masa, tetapi fungsi kutu sentiasa dilaksanakan. Jika program pelayan menerima 1,000 permintaan dalam 1 saat, secara purata setiap permintaan akan melaksanakan 1,000 baris kod PHP. Kemudian pcntl_signal PHP membawa tambahan 1000 * 1000, iaitu 1 juta panggilan fungsi kosong. Ini akan membazirkan banyak sumber CPU. Pendekatan yang lebih baik ialah membuang tanda kutu dan sebaliknya gunakan pcntl_signal_dispatch untuk mengendalikan sendiri isyarat dalam gelung kod. Pelaksanaan fungsi pcntl_signal_dispatch: Tetapi perkara seperti di atas juga mempunyai bahagian yang menjijikkan, iaitu, ia perlu diletakkan dalam gelung yang tidak terhingga. Selepas PHP7.1, fungsi yang melengkapkan penerimaan dan pemprosesan isyarat tak segerak keluar: pcntl_async_signalsDengan kaedah pcntl_async_signals, tidak perlu menulis gelung tak terhingga.

监听信号的包:

https://github.com/Rain-Life/monitorSignal

Atas ialah kandungan terperinci Pemahaman menyeluruh tentang pemprosesan isyarat proses PHP dalam satu artikel. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.im. Jika ada pelanggaran, sila hubungi admin@php.cn Padam