溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

PHP多進(jìn)程開發(fā)面試的常見問題怎么解決

發(fā)布時(shí)間:2022-12-27 10:34:36 來源:億速云 閱讀:126 作者:iii 欄目:編程語言

本篇內(nèi)容介紹了“PHP多進(jìn)程開發(fā)面試的常見問題怎么解決”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

PHP多進(jìn)程開發(fā)

先介紹一些簡單命令

echo $$ //輸出當(dāng)前bash進(jìn)程
strace -s 65500 -p 進(jìn)程號(hào)    //打印進(jìn)程系統(tǒng)調(diào)用
kill -s 10 pid //發(fā)送信號(hào)
kill -s SIGUSR2 pid //發(fā)送信號(hào)
pstree -ap //查看進(jìn)程樹
ps -ajx //查看進(jìn)程信息
ps 命令字段解析:
PPID:父進(jìn)程ID
PID:進(jìn)程ID
PGID:進(jìn)程組ID
SID:會(huì)話ID
TTY:所在終端
STAT:進(jìn)程狀態(tài) R運(yùn)行 Z僵尸 S睡眠 T停止 D睡眠無法被喚醒
UID:unix用戶ID
COMMAND:啟動(dòng)命令

什么是程序?

一般指可執(zhí)行文件,在 Linux 系統(tǒng)中它按 ELF 格式進(jìn)行存儲(chǔ),沒有后綴可言,file 命令可以查看 elf 文件的具體類型

ELF 全程 Executable Linkable Format 可執(zhí)行可鏈接格式

ELF 分為四大種類

  • EXEC 可執(zhí)行文件

  • REL 可重定位文件,也稱為靜態(tài)庫文件,鏈接器鏈接之后成為動(dòng)態(tài)庫文件,比如 event.so sockets.so curl.so

  • Shared Object File 共享目標(biāo)文件

  • core dump 存儲(chǔ)進(jìn)程產(chǎn)生的異常信息

可通過 objdump/readelf 命令查看 ELF 文件相關(guān)信息

什么是終端?

  • tty 物理終端

tty 是最令人熟悉的了,在 Linux 中,/dev/ttyX 代表的都是上述的物理終端,其中,/dev/tty1~/dev/tty63 代表的是本地終端,也就是接到本機(jī)的鍵盤顯示器可以操作的終端

/dev/console 當(dāng)前焦點(diǎn)終端

  • pts 偽終端

通過 tcp/ip 協(xié)議實(shí)現(xiàn)的終端,比如用 SSH 進(jìn)行的登錄,或者 telnet, 那么你將得到一個(gè)叫做 /dev/pts/X 的偽終端同時(shí)在

/proc/bash pid/fd 生成三個(gè)標(biāo)識(shí)符指向當(dāng)前的 /dev/pts/X

0 標(biāo)準(zhǔn)輸入 鼠標(biāo),鍵盤

1 標(biāo)準(zhǔn)輸出 顯示器

2 標(biāo)準(zhǔn)錯(cuò)誤 顯示器

PHP多進(jìn)程開發(fā)面試的常見問題怎么解決

什么是進(jìn)程?

進(jìn)程退出

  • 運(yùn)行到最后一行語句

  • 運(yùn)行時(shí)遇到 return 時(shí)

  • 運(yùn)行時(shí)遇到 exit () 函數(shù)的時(shí)候

  • 程序異常的時(shí)候

  • 進(jìn)程接收到中斷信號(hào)

進(jìn)程結(jié)束時(shí)并不會(huì)真的退出,還會(huì)駐留在內(nèi)在中,pcntl_wait (pcntl_waitpid) 函數(shù)來獲取進(jìn)程的終止?fàn)顟B(tài)碼同時(shí)該函數(shù)會(huì)釋放終止進(jìn)程的內(nèi)存空間,如果不這么做,會(huì)產(chǎn)生很多僵尸進(jìn)程占用大量的內(nèi)存空間

孤兒進(jìn)程

父進(jìn)程運(yùn)行完,子進(jìn)程在運(yùn)行,則子進(jìn)程會(huì)被頭號(hào)進(jìn)程 init 接管,這類型的進(jìn)程成為孤兒進(jìn)程

僵尸進(jìn)程

子進(jìn)程運(yùn)行完,父進(jìn)程沒有調(diào)用 pcntl_wait () 回收,進(jìn)程狀態(tài)變成 Z+

守護(hù)進(jìn)程

父進(jìn)程是 init 進(jìn)程,一般在系統(tǒng)啟動(dòng)時(shí)開始運(yùn)行,除非強(qiáng)行終止,否則直到系統(tǒng)關(guān)機(jī)都保持運(yùn)行。守護(hù)進(jìn)程經(jīng)常以超級(jí)用戶(root)權(quán)限運(yùn)行,因?yàn)樗鼈円褂锰厥獾亩丝冢?-1024)或訪問某些特殊的資源。

什么是進(jìn)程組?

多個(gè)進(jìn)程組成一個(gè)進(jìn)程組,每個(gè)進(jìn)程組只有一個(gè)組長,組長的 PID 就是進(jìn)程組的 ID;組內(nèi)所有進(jìn)程退出時(shí),進(jìn)程組才會(huì)消失,可以通過 ps -ajx 命令查看 pgid

PHP多進(jìn)程開發(fā)面試的常見問題怎么解決

什么是會(huì)話?

多個(gè)進(jìn)程組組成一個(gè)會(huì)話,每個(gè)會(huì)話都有一個(gè)會(huì)話首進(jìn)程。會(huì)話的特點(diǎn)

1) 使用 setsid () 函數(shù)可以創(chuàng)建一個(gè)新的會(huì)話

2) 會(huì)話首進(jìn)程無法調(diào)用 setsid,會(huì)報(bào)錯(cuò)

3) 非會(huì)話首進(jìn)程進(jìn)程可調(diào)用 setsid 創(chuàng)建出一個(gè)新的會(huì)話,這個(gè)行為會(huì)導(dǎo)致該進(jìn)程會(huì)創(chuàng)建一個(gè)新的進(jìn)程組且自身為該進(jìn)程組組長,該進(jìn)程會(huì)創(chuàng)建出一個(gè)新的會(huì)話組且自身為該會(huì)話組組長,該進(jìn)程會(huì)脫離當(dāng)前命令行控制終端

現(xiàn)實(shí)上的比喻就是除了老板之后,員工都可以調(diào)用 我上我也行 () 這個(gè)函數(shù)變成老板且不受原公司的控制

什么是信號(hào)?

信號(hào)是進(jìn)程間通信的其中一種方式,平時(shí)用到的 kill -9 pid, 指的不是用第九種方式殺死進(jìn)程,而是發(fā)送信號(hào)值為 9 的信號(hào)給進(jìn)程,而剛好信號(hào) 9 是 SIGKILL, 功能是停止進(jìn)程,查看操作系統(tǒng)支持的信號(hào)命令: kill -l

PHP多進(jìn)程開發(fā)面試的常見問題怎么解決

一般使用 1-31, 注意看沒有 32,33 這兩個(gè)信號(hào)

信號(hào)的產(chǎn)生來源可能是:

  • 鍵盤上按了 Ctrl+C 會(huì)產(chǎn)生 SIGINT 信號(hào),關(guān)閉終端會(huì)產(chǎn)生 SIGHUP 信號(hào)

  • 硬件也能產(chǎn)生信號(hào)

  • 使用 kill 命令

  • 軟件產(chǎn)生,比如在管道里當(dāng)一側(cè)準(zhǔn)備寫管道時(shí)可能會(huì)產(chǎn)生 SIGPIPE 信號(hào)

當(dāng)一個(gè)進(jìn)程收到一個(gè)信號(hào)時(shí),三個(gè)可選操作

  • 操作系統(tǒng)默認(rèn)的方式,比如 SIGKILL 就是殺死進(jìn)程

  • 忽略掉這個(gè)信號(hào),pcntl_signal (SIGKILL, SIG_IGN, false); 進(jìn)程收到 SIGKILL 命令時(shí)將不為所動(dòng)

  • 有自己的想法,pcntl_signal (SIGKILL, function ($signal){// 自己的想法}, false); 這樣將會(huì)觸發(fā)自定義回調(diào)

pcntl_signal () 信號(hào)處理器是會(huì)被子進(jìn)程繼承的,所以 fork () 之前最后先行處理信號(hào)處理器

posix 命令

//需要安裝posix擴(kuò)展
posix_getpid();    //獲取進(jìn)程ID
posix_getppid();//獲取父進(jìn)程ID
posix_getpgid(posix_getppid());//獲取進(jìn)程組ID
posix_getpgrp());//同上
posix_getsid(posix_getpid()));//獲取會(huì)話ID
posix_getuid();//獲取當(dāng)前登錄用戶UID
posix_getgid();//獲取當(dāng)前登錄用戶組UID
posix_geteuid();//獲取當(dāng)前有效用戶UID
posix_getguid();//獲取當(dāng)前有效用戶組UID
posix_kill();//發(fā)送信號(hào)

pcntl 命令

//創(chuàng)建一個(gè)計(jì)時(shí)器,在指定的秒數(shù)后向進(jìn)程發(fā)送一個(gè)SIGALRM信號(hào)。每次對(duì) pcntl_alarm()的調(diào)用都會(huì)取消之前設(shè)置的alarm信號(hào)。如果seconds設(shè)置為0,將不會(huì)創(chuàng)建alarm信號(hào)。 
pcntl_alarm(int $seconds);
//在當(dāng)前進(jìn)程當(dāng)前位置產(chǎn)生子進(jìn)程,子進(jìn)程會(huì)復(fù)制父進(jìn)程的代碼段和數(shù)據(jù)段(Copy on write 寫時(shí)復(fù)制,當(dāng)子進(jìn)程要修改內(nèi)存空間時(shí),操作系統(tǒng)會(huì)分配新的內(nèi)存給子進(jìn)程),ELF文件的結(jié)構(gòu),如果父進(jìn)程先退出,子進(jìn)程變成孤兒進(jìn)程,被pid=1進(jìn)程接管
pcntl_fork();
//安裝一個(gè)信號(hào)處理器
pcntl_signal(int $signo, callback $handler);
//調(diào)用等待信號(hào)的處理器,觸發(fā)全部未執(zhí)行的信號(hào)回調(diào)
pcntl_signal_dispatch()
//設(shè)置或檢索阻塞信號(hào)
pcntl_sigprocmask(int $how, array $set[, array &$oldset])
//等待或返回fork的子進(jìn)程狀態(tài),wait函數(shù)掛起當(dāng)前進(jìn)程的執(zhí)行直到一個(gè)子進(jìn)程退出或接收到一個(gè)信號(hào)要求中斷當(dāng)前進(jìn)程或調(diào)用一個(gè)信號(hào)處理函數(shù)。用此函數(shù)時(shí)已經(jīng)退出(俗稱僵尸進(jìn)程),此函數(shù)立刻返回。子進(jìn)程使用的所有系統(tǒng)資源將被釋放。
pcntl_wait($status)
//加個(gè)WNOHANG參數(shù),不掛起父進(jìn)程,如果沒有子進(jìn)程退出返回0,如果有子進(jìn)程退出返回子進(jìn)程pid,如果返回-1表示父進(jìn)程已經(jīng)沒有子進(jìn)程
pcntl_wait($status, WNOHANG)
//基本同pcntl_wait,waitpid可以指定子進(jìn)程id
pcntl_waitpid ($pid ,$status)
pcntl_waitpid ($pid ,$status, WNOHANG)
//檢查狀態(tài)代碼是否代表一個(gè)正常的退出。參數(shù) status 是提供給成功調(diào)用 pcntl_waitpid() 時(shí)的狀態(tài)參數(shù)。
pcntl_wifexited($status)
//返回一個(gè)中斷的子進(jìn)程的返回代碼  當(dāng)php exit(10)時(shí),這個(gè)函數(shù)返回10,這個(gè)函數(shù)僅在函數(shù)pcntl_wifexited()返回 TRUE.時(shí)有效
pcntl_wexitstatus($status)
//檢查子進(jìn)程狀態(tài)碼是否代表由于某個(gè)信號(hào)而中斷。參數(shù) status 是提供給成功調(diào)用 pcntl_waitpid() 時(shí)的狀態(tài)參數(shù)。
pcntl_wifsignaled($status)
//返回導(dǎo)致子進(jìn)程中斷的信號(hào)
pcntl_wtermsig($status)
//檢查子進(jìn)程當(dāng)前是否已經(jīng)停止,此函數(shù)只有作用于pcntl_wait使用了WUNTRACED作為 option的時(shí)候
pcntl_wifstopped($status)
//返回導(dǎo)致子進(jìn)程停止的信號(hào)
pcntl_wstopsig($status)
//檢索由最后一個(gè)失敗的pcntl函數(shù)設(shè)置的錯(cuò)誤數(shù)
pcntl_errno() 
pcntl_get_last_error()
//檢索與給定errno關(guān)聯(lián)的系統(tǒng)錯(cuò)誤消息
pcntl_strerror(pcntl_errno())

pcntl_fork () 執(zhí)行之前先與 Redis 建立一個(gè)連接,然后再開 3 個(gè)子進(jìn)程之后多少個(gè) Redis 連接?

<?php
$o_redis = new Redis();
$o_redis->connect( '127.0.0.1', 6379 );
// 使用for循環(huán)搞出3個(gè)子進(jìn)程來
for ( $i = 1; $i <= 3; $i++ ) {
  $i_pid = pcntl_fork();
  if ( 0 == $i_pid ) {
    // 使用while保證三個(gè)子進(jìn)程不會(huì)退出...
    while( true ) {
      sleep( 1 );
    }
  }
}
// 使用while保證主進(jìn)程不會(huì)退出...
while( true ) { 
  sleep( 1 );
}


netstat -ant |grep 6379

PHP多進(jìn)程開發(fā)面試的常見問題怎么解決

說明父進(jìn)程和三個(gè)子進(jìn)程一共四個(gè)進(jìn)程,實(shí)際上共享了一個(gè) Redis 長連接

上面這種寫法會(huì)有什么問題?

因?yàn)?Redis 是一個(gè)單進(jìn)程單線程的服務(wù)器,所以接收到的命令都是順序執(zhí)行順序返回的,所以當(dāng)客戶端多個(gè)進(jìn)程共享一個(gè) redis 連接時(shí),當(dāng)有四個(gè)進(jìn)程向 Redis 服務(wù)端發(fā)起請(qǐng)求,返回四個(gè)結(jié)果,誰先搶到就是誰的,正確的做法是每個(gè)子進(jìn)程創(chuàng)建一個(gè) Redis 連接,或者用連接池

孤兒進(jìn)程怎么產(chǎn)生?

$i_pid = pcntl_fork();
if (0 == $i_pid) {
    // 子進(jìn)程10秒鐘后退出.
    for ($i = 1; $i <= 10; $i++) {
        sleep(1);
        echo "我的父進(jìn)程是:" . posix_getppid() . PHP_EOL;
    }
} else if ($i_pid > 0) {
    // 父進(jìn)程休眠2s后退出.
    sleep(2);
}

僵尸進(jìn)程怎么產(chǎn)生?

$i_pid = pcntl_fork();
if (0 == $i_pid) {
    // 子進(jìn)程10s后退出,變成僵尸進(jìn)程
    sleep(10);
} else if ($i_pid > 0) {
    // 父進(jìn)程休眠1000s后退出.
    sleep(1000);
}

子進(jìn)程怎么回收?

$i_pid = pcntl_fork();
if (0 == $i_pid) {
    // 在子進(jìn)程中
    for ($i = 1; $i <= 10; $i++) {
        sleep(1);
        echo "子進(jìn)程PID " . posix_getpid() . "倒計(jì)時(shí) : " . $i . PHP_EOL;
    }
} else if ($i_pid > 0) {
    $i_ret = pcntl_wait($status);
    echo $i_ret . ' : ' . $status . PHP_EOL;
    // while保持父進(jìn)程不退出
    while (true) {
        sleep(1);
    }
}

子進(jìn)程怎么回收?非阻塞版本

<?php
// fork出十個(gè)子進(jìn)程
for ($i = 1; $i <= 10; $i++) {
    $i_pid = pcntl_fork();
    // 每個(gè)子進(jìn)程隨機(jī)運(yùn)行1-5秒鐘
    if (0 == $i_pid) {
        $i_rand_time = mt_rand(1, 5);
        sleep($i_rand_time);
        exit;
    } // 父進(jìn)程收集所有子進(jìn)程PID
    else if ($i_pid > 0) {
    }
}
while (true) {
    // sleep使父進(jìn)程不會(huì)因while導(dǎo)致CPU爆炸.
    sleep(1);
    //設(shè)置WNOHANG參數(shù)不會(huì)阻塞,就是需要外層包個(gè)循環(huán)
    $pid = pcntl_wait($status, WNOHANG);
    if ($pid == 0) {   //目前還沒有結(jié)束的子進(jìn)程
        continue;
    }
    if ($pid == -1) { //已經(jīng)結(jié)束啦 很藍(lán)的啦
        exit("所有進(jìn)程均已終止" . PHP_EOL);
    }
    // 如果子進(jìn)程是正常結(jié)束
    if (pcntl_wifexited($status)) {
        // 獲取子進(jìn)程結(jié)束時(shí)候的 返回錯(cuò)誤碼
        $i_code = pcntl_wexitstatus($status);
        echo $pid . "正常結(jié)束,最終返回:" . $i_code . PHP_EOL;
    }
    // 如果子進(jìn)程是被信號(hào)終止
    if (pcntl_wifsignaled($status)) {
        // 獲取是哪個(gè)信號(hào)終止的該進(jìn)程
        $i_signal = pcntl_wtermsig($status);
        echo $pid . "由信號(hào)結(jié)束,信號(hào)為:" . $i_signal . PHP_EOL;
    }
    // 如果子進(jìn)程是[臨時(shí)掛起]
    if (pcntl_wifstopped($status)) {
        // 獲取是哪個(gè)信號(hào)讓他掛起
        $i_signal = pcntl_wstopsig($status);
        echo $pid . "被掛起,掛起信號(hào)為:" . $i_signal . PHP_EOL;
    }
}

如何創(chuàng)建守護(hù)進(jìn)程?

$pid = pcntl_fork();
if ($pid > 0) { //1)在父進(jìn)程中執(zhí)行fork并exit推出
    exit();
} elseif ($pid == 0) {
    if (posix_setsid() < 0) {   //2)在子進(jìn)程中調(diào)用setsid函數(shù)創(chuàng)建新的會(huì)話
        exit();
    }
    chdir('/'); //3)在子進(jìn)程中調(diào)用chdir函數(shù),讓根目錄 ” / ” 成為子進(jìn)程的工作目錄
    umask(0);   //4)在子進(jìn)程中調(diào)用umask函數(shù),設(shè)置進(jìn)程的umask為0
    echo "create success, pid = " . posix_getpid();
    //5)在子進(jìn)程中關(guān)閉任何不需要的文件描述符
    fclose(STDIN);
    fclose(STDOUT);
    fclose(STDERR);
}
//可以把上面封裝成函數(shù)daemon();
while (true) {} //具體業(yè)務(wù)
如何修改進(jìn)程名?
for ($i = 1; $i <= 4; $i++) {
    $i_pid = pcntl_fork();
    if (0 == $i_pid) { //子進(jìn)程
        cli_set_process_title("Worker Process"); //修改子進(jìn)程的名字
        while (true) {
            sleep(1);
        }
    }
}
cli_set_process_title("Master Process");    //修改父進(jìn)程的名字
while (true) {
    sleep(1);
}

PHP多進(jìn)程開發(fā)面試的常見問題怎么解決

進(jìn)程怎么接收信號(hào)?

// 信號(hào)處理回調(diào)
function signal_handler($signal)
{
    switch ($signal) {
        case SIGTERM:
            echo "sigterm信號(hào)." . PHP_EOL;
            break;
        case SIGUSR2:
            echo "sigusr2信號(hào)." . PHP_EOL;
            break;
        case SIGUSR1:
            echo "sigusr1信號(hào)." . PHP_EOL;
            break;
        default:
            echo "其他信號(hào)." . PHP_EOL;
    }
}
// 給進(jìn)程安裝3個(gè)信號(hào)處理回調(diào)
pcntl_signal(SIGTERM, "signal_handler");
pcntl_signal(SIGUSR1, "signal_handler");
pcntl_signal(SIGUSR2, "signal_handler");
while (true) {
    posix_kill(posix_getpid(), SIGUSR1);//發(fā)送一個(gè)信號(hào)給當(dāng)前進(jìn)程
    posix_kill(posix_getpid(), SIGUSR1);
    pcntl_signal_dispatch(); //調(diào)一次分發(fā)一次信號(hào),調(diào)用之前,信號(hào)累積在隊(duì)列里
    posix_kill(posix_getpid(), SIGUSR2);
    posix_kill(posix_getpid(), SIGUSR2);
    sleep(1);   //稍微休息一下
}

PHP多進(jìn)程開發(fā)面試的常見問題怎么解決

其中第 1,2 行與第 3,4,5,6 行中間隔了一秒,體會(huì)一下 pcntl_signal_dispatch 這個(gè)函數(shù)

進(jìn)程怎么接收信號(hào) (不阻塞版本)?

//php7.1及以上才能用這個(gè)函數(shù)
pcntl_async_signals(true);
// 信號(hào)處理回調(diào)
function signal_handler($signal)
{
    switch ($signal) {
        case SIGTERM:
            echo "sigterm信號(hào)." . PHP_EOL;
            break;
        case SIGUSR2:
            echo "sigusr2信號(hào)." . PHP_EOL;
            break;
        case SIGUSR1:
            echo "sigusr1信號(hào)." . PHP_EOL;
            break;
        default:
            echo "其他信號(hào)." . PHP_EOL;
    }
}
// 給進(jìn)程安裝信號(hào)...
pcntl_signal(SIGTERM, "signal_handler");
pcntl_signal(SIGUSR1, "signal_handler");
pcntl_signal(SIGUSR2, "signal_handler");
while (true) {
    posix_kill(posix_getpid(), SIGUSR1);//發(fā)送一個(gè)信號(hào)給當(dāng)前進(jìn)程
    posix_kill(posix_getpid(), SIGUSR2);
    sleep(1);   //稍微休息一下
}

進(jìn)程怎么阻塞信號(hào)

pcntl_async_signals(true);
// 信號(hào)處理回調(diào)
function signal_handler($signal)
{
    switch ($signal) {
        case SIGTERM:
            echo "sigterm信號(hào)." . PHP_EOL;
            break;
        case SIGUSR2:
            echo "sigusr2信號(hào)." . PHP_EOL;
            break;
        case SIGUSR1:
            echo "sigusr1信號(hào)." . PHP_EOL;
            break;
        default:
            echo "其他信號(hào)." . PHP_EOL;
    }
}
// 給進(jìn)程安裝信號(hào)...
pcntl_signal(SIGTERM, "signal_handler");
pcntl_signal(SIGUSR1, "signal_handler");
pcntl_signal(SIGUSR2, "signal_handler");
//把SIGUSR1阻塞,收到這個(gè)信號(hào)先不處理
pcntl_sigprocmask(SIG_BLOCK, [SIGUSR1], $a_oldset);
$counter = 0;
while (true) {
    posix_kill(posix_getpid(), SIGUSR1);//發(fā)送一個(gè)信號(hào)給當(dāng)前進(jìn)程
    posix_kill(posix_getpid(), SIGUSR2);
    sleep(1);   //稍微休息一下
    if ($counter++ == 5) {
        //解除SIGUSR1信號(hào)阻塞,并立刻執(zhí)行SIGUSR1處理回調(diào)函數(shù)
        pcntl_sigprocmask(SIG_UNBLOCK, [SIGUSR1], $a_oldset);
    }
}

“PHP多進(jìn)程開發(fā)面試的常見問題怎么解決”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

php
AI