찾다
백엔드 개발PHP 튜토리얼PHP는 시스템 프로그래밍을 구현합니다: 다중 프로세스 프로그래밍과 고아 프로세스 및 좀비 프로세스 소개

이 기사의 내용은 PHP 시스템 프로그래밍에서 다중 프로세스 프로그래밍과 고아 프로세스 및 좀비 프로세스의 소개를 공유하는 것입니다. 필요한 친구가 참조할 수 있습니다.

다중 프로세스 프로그래밍은 시스템 프로그래밍의 일부이기도 하지만 PHP 프로그래머는 일반적으로 다중 프로세스 문제에 신경 쓸 필요가 없습니다. 왜냐하면 웹 서버나 PHP-FPM이 이미 프로세스 문제를 관리해 주었기 때문입니다. 하지만 PHP를 사용하여 개발하려는 경우에는 CLI 프로그램, 멀티프로세스 프로그래밍은 필수적인 기본 기술입니다.

PHP의 프로세스 제어 방법은 주로 PCNTL(Process Control) 확장을 사용합니다. 따라서 다중 프로세스 프로그래밍을 수행하기 전에 먼저 PHP에 최신 PCNTL 확장이 설치되어 있는지 확인해야 합니다. php를 입력할 수 있습니다. - 현재 설치된 확장을 보기 위한 m 명령:



이 확장은 프로세스 작업을 위한 일련의 메소드를 제공합니다:

PCNTL 函数
pcntl_alarm — 为进程设置一个alarm闹钟信号
pcntl_errno — 别名 pcntl_get_last_error
pcntl_exec — 在当前进程空间执行指定程序
pcntl_fork — 在当前进程当前位置产生分支(子进程)。
pcntl_get_last_error — Retrieve the error number set by the last pcntl function which failed
pcntl_getpriority — 获取任意进程的优先级
pcntl_setpriority — 修改任意进程的优先级
pcntl_signal_dispatch — 调用等待信号的处理器
pcntl_signal_get_handler — Get the current handler for specified signal
pcntl_signal — 安装一个信号处理器
pcntl_sigprocmask — 设置或检索阻塞信号
pcntl_sigtimedwait — 带超时机制的信号等待
pcntl_sigwaitinfo — 等待信号
pcntl_strerror — Retrieve the system error message associated with the given errno
pcntl_wait — 等待或返回fork的子进程状态
pcntl_waitpid — 等待或返回fork的子进程状态
pcntl_wexitstatus — 返回一个中断的子进程的返回代码
pcntl_wifexited — 检查状态代码是否代表一个正常的退出。
pcntl_wifsignaled — 检查子进程状态码是否代表由于某个信号而中断
pcntl_wifstopped — 检查子进程当前是否已经停止
pcntl_wstopsig — 返回导致子进程停止的信号
pcntl_wtermsig — 返回导致子进程中断的信号


pcntl_fork현재 프로세스의 현재 위치에 브랜치(자식 프로세스)를 생성합니다. 주석: 포크는 하위 프로세스, 상위 프로세스 및 하위 프로세스를 생성합니다. 모두 포크 위치에서 시작하여 아래쪽으로 계속됩니다. 차이점은 부모 프로세스를 실행하는 동안 얻은 포크 반환 값은 자식 프로세스 번호이고 자식 프로세스는 0을 얻는다는 것입니다.

분할된 하위 프로세스는 상위 프로세스의 거의 완전한 복사본입니다. 상위 및 하위 프로세스는 코드 세그먼트를 공유하지만 상위 및 하위 프로세스의 데이터 세그먼트, 힙 및 스택은 서로 독립적입니다. 처음에는 하위 프로세스가 완전히 상위 프로세스의 데이터가 복사되지만 이후 수정 사항은 서로 영향을 미치지 않습니다.


int pcntl_fork ( void )


5개의 하위 프로세스 생성 코드 데모:

<?php

for($i = 0; $i < 5; $i++)
{
        $pid = pcntl_fork();  //创建子进程,子进程也是从这里开始执行。

        if ($pid == 0)
        {
                break; //由于子进程也会执行循环的代码,所以让子进程退出循环,否则子进程又会创建自己的子进程。
        }
}

sleep($i);  //第一个创建的子进程将睡眠0秒,第二个将睡眠1s,依次类推...主进程会睡眠5秒

if ($i < 5)
{
        exit("第 " . ($i+1) . " 个子进程退出..." . time() . PHP_EOL);
}
else
{
        exit("父进程退出..." . time() . PHP_EOL);
}


실행 결과:


[root@localhost process]# php process.php 
第 1 个子进程退出...1503322773
第 2 个子进程退出...1503322774
第 3 个子进程退出...1503322775
第 4 个子进程退出...1503322776
第 5 个子进程退出...1503322777
父进程退出...1503322778


pcntl_fork 함수에 대해 이해해야 할 핵심 사항: fork는 하위 프로세스를 생성합니다. 상위 프로세스와 하위 프로세스 모두 포크 위치에서 계속 실행됩니다. 차이점은 상위 프로세스 실행 중에 포크가 반환된다는 것입니다. 값은 하위 프로세스 번호이고 하위 프로세스는 0"을 얻습니다.



프로세스가 종료되지 않도록 위 코드를 약간 수정한 다음 ps 명령을 사용하여 시스템 상태를 확인합니다.

<?php

for($i = 0; $i < 5; $i++)
{
        $pid = pcntl_fork();

        if ($pid == 0)
        {
                break; //由于子进程也会执行循环的代码,所以让子进程退出循环
        }
}

sleep($i);  //第一个创建的子进程将睡眠0秒,第二个将睡眠1s,依次类推...主进程会睡眠5秒

/*
if ($i < 5)
{
        exit("第 " . ($i+1) . " 个子进程退出..." . time() . PHP_EOL);
}
else
{
        exit("父进程退出..." . time() . PHP_EOL);
}
*/

while(1)
{
        sleep(1);       //执行死循环不退出
}


실행 후 ps -ef | grep php 를 입력하면 시스템 프로세스를 볼 수 있습니다


[root@localhost ~]# ps -ef | grep php
root      3670  3609  0 21:54 pts/0    00:00:00 php process.php
root      3671  3670  0 21:54 pts/0    00:00:00 php process.php
root      3672  3670  0 21:54 pts/0    00:00:00 php process.php
root      3673  3670  0 21:54 pts/0    00:00:00 php process.php
root      3674  3670  0 21:54 pts/0    00:00:00 php process.php
root      3675  3670  0 21:54 pts/0    00:00:00 php process.php
root      3677  3646  0 21:54 pts/1    00:00:00 grep php


6개의 php process.php 프로세스를 볼 수 있습니다. 는 프로세스 번호이고 세 번째 열은 프로세스의 상위 프로세스 번호입니다. 다음 5개 프로세스의 상위 프로세스 번호는 모두 첫 번째 프로세스의 프로세스 번호임을 알 수 있습니다.


위 코드는 하위 프로세스와 상위 프로세스 모두 동일한 코드를 실행합니다. 하위 프로세스와 상위 프로세스가 서로 다른 작업을 수행하도록 하는 방법이 있습니까? 프로세스가 하위 프로세스를 실행합니다. 상위 프로세스의 코드가 상위 프로세스의 코드를 실행합니다.

<?php
$ppid = posix_getpid(); //记录父进程的进程号

for($i = 0; $i < 5; $i++)
{
        $pid = pcntl_fork();

        if ($pid == 0)
        {       
                break; //由于子进程也会执行循环的代码,所以让子进程退出循环
        }
}

if ($ppid == posix_getpid())
{
        //父进程
        while(1)
        {
                sleep(1);
        }
}
else
{
        //子进程
        for($i = 0; $i < 100; $i ++)
        {
                echo "子进程" . posix_getpid() . " 循环 $i ...\n";
                sleep(1);
        }
}


[root@localhost process]# php process.php 
子进程6677 循环 0 ...
子进程6676 循环 0 ...
子进程6678 循环 0 ...
子进程6680 循环 0 ...
子进程6679 循环 0 ...
子进程6677 循环 1 ...
子进程6676 循环 1 ...
子进程6678 循环 1 ...
子进程6680 循环 1 ...
子进程6679 循环 1 ...
子进程6677 循环 2 ...
子进程6676 循环 2 ...
子进程6678 循环 2 ...
子进程6680 循环 2 ...


실제로 위 프로그램의 상위 프로세스와 하위 프로세스는 여전히 동일한 코드를 실행합니다. , 그러나 입력된 if 분기가 다르며 pcntl_exec는 하위 프로세스가 상위 프로세스의 영향을 완전히 벗어나 새 프로그램을 실행하도록 할 수 있습니다.


pcntl_exec — 在当前进程空间执行指定程序

void pcntl_exec ( string $path [, array $args [, array $envs ]] )

path
path必须时可执行二进制文件路径或一个在文件第一行指定了 一个可执行文件路径标头的脚本(比如文件第一行是#!/usr/local/bin/perl的perl脚本)。 更多的信息请查看您系统的execve(2)手册。

args
args是一个要传递给程序的参数的字符串数组。

envs
envs是一个要传递给程序作为环境变量的字符串数组。这个数组是 key => value格式的,key代表要传递的环境变量的名称,value代表该环境变量值。

注意该方法的返回值比较特殊:当发生错误时返回 FALSE ,没有错误时没有返回,因为pcntl_exec调用成功,子进程就去运行新的程序 从父进程继承的代码段、数据段、堆、栈等信息全部被替换成新的,此时的pcntl_exec函数调用栈已经不存在了,所以也就没有返回了。代码示例:

<?php
for($i = 0; $i < 3; $i++)
{
        $pid = pcntl_fork();

        if($pid == 0)
        {
                echo "子进程pid = " . posix_getpid() . PHP_EOL;
                $ret = pcntl_exec(&#39;/bin/ls&#39;);  //执行 ls 命令, 此处调用成功子进程将不会再回来执行下面的任何代码
                var_dump($ret); // 此处的代码不会再执行
        }
}

sleep(5);  //睡眠5秒以确保子进程执行完毕,原因后面会说

exit( "主进程退出...\n");

运行结果:

[root@localhost process]# php pcntl_exec.php 
子进程pid = 6728
子进程pid = 6729
子进程pid = 6727
pcntl_exec.php	process.php
pcntl_exec.php	process.php
pcntl_exec.php	process.php
主进程退出...
[root@localhost process]# ls
pcntl_exec.php  process.php

以上就是对PHP多进程开发的简单介绍,对于子进程不同的存续状态,引出孤儿进程和僵尸进程的概念,在linux系统中,init进程(1号进程)是所有进程的祖先,其他进程要么是该进程的子进程,要么是子进程的子进程,子进程的子进程的子进程...,linux系统中可以用 pstree 命令查看进程树结构:


在多进程程序中,如果父进程先于子进程退出,那么子进程将会被init进程收养,成为init进程的子进程,这种进程被称为孤儿进程,我们可以把上面的代码稍作修改来演示这种情况:


<?php
$ppid = posix_getpid(); //记录父进程的进程号

for($i = 0; $i < 5; $i++)
{
        $pid = pcntl_fork();

        if ($pid == 0)
        {       
                break; //由于子进程也会执行循环的代码,所以让子进程退出循环
        }
}

if ($ppid == posix_getpid())
{
        //父进程直接退出,它的子进程都会成为孤儿进程
        exit(0);
}
else
{
        //子进程
        for($i = 0; $i < 100; $i ++)
        {
                echo "子进程" . posix_getpid() . " 循环 $i ...\n";
                sleep(1);
        }
}

运行该程序,然后查看进程状态:


[root@localhost ~]# ps -ef | grep php
root      2903     1  0 12:09 pts/0    00:00:00 php pcntl.fork.php
root      2904     1  0 12:09 pts/0    00:00:00 php pcntl.fork.php
root      2905     1  0 12:09 pts/0    00:00:00 php pcntl.fork.php
root      2906     1  0 12:09 pts/0    00:00:00 php pcntl.fork.php
root      2907     1  0 12:09 pts/0    00:00:00 php pcntl.fork.php
root      2935  2912  0 12:10 pts/1    00:00:00 grep php


可以看到五个子进程的父进程号都是1了,并且这时控制台不再被程序占用,子进程转到了后台运行,这种孤儿进程被init进程收养的机制是实现后面将要介绍的守护进程的必要条件之一。

子进程还有一种状态叫僵尸进程,子进程结束时并不是完全退出,内核进程表中仍旧保有该进程的记录,这样做的目的是能够让父进程可以得知子进程的退出状态,以及子进程是自杀(调用exit或代码执行完毕)还是他杀(被信号终止),父进程可以调用pcntl_wait 或 pcntl_waitpid 方法来回收子进程(收尸),释放子进程占用的所有资源,并获得子进程的退出状态,如果父进程不做回收,则僵尸进程一直存在,如果这时父进程也退出了,则这些僵尸进程会被init进程接管并自动回收。

对于linux系统来说,一个长时间运行的多进程程序一定要回收子进程,因为系统的进程资源是有限的,僵尸进程会让系统的可用资源减少。

代码演示僵尸进程的产生:

<?php
$ppid = posix_getpid(); //记录父进程的进程号

for($i = 0; $i < 5; $i++)
{
        $pid = pcntl_fork();

        if ($pid == 0)
        {
                break; //由于子进程也会执行循环的代码,所以让子进程退出循环
        }
}

if ($ppid == posix_getpid())
{
        //父进程不退出,也不回收子进程
        while(1)
        {
                sleep(1);
        }
}
else
{
        //子进程退出,会成为僵尸进程
                exit("子进程退出 $ppid ...\n");
}

运行之后查看进程状态:

[root@localhost ~]# ps -ef | grep php
root      2971  2864  0 14:13 pts/0    00:00:00 php pcntl.fork.php
root      2972  2971  0 14:13 pts/0    00:00:00 [php] <defunct>
root      2973  2971  0 14:13 pts/0    00:00:00 [php] <defunct>
root      2974  2971  0 14:13 pts/0    00:00:00 [php] <defunct>
root      2975  2971  0 14:13 pts/0    00:00:00 [php] <defunct>
root      2976  2971  0 14:13 pts/0    00:00:00 [php] <defunct>
root      2978  2912  0 14:13 pts/1    00:00:00 grep php


僵尸进程会用 (死者,死人) 来标识,除非我们结束父进程,否则这些僵尸进程会一直存在,也无法用kill命令来杀死。

PHP的pcntl扩展提供了两个回收子进程的方法供我们调用:



int pcntl_wait ( int &$status [, int $options = 0 ] )
int pcntl_waitpid ( int $pid , int &$status [, int $options = 0 ] )


pcntl_wait函数挂起当前进程的执行直到一个子进程退出或接收到一个信号要求中断当前进程或调用一个信号处理函数。 如果一个子进程在调用此函数时已经退出(俗称僵尸进程),此函数立刻返回。子进程使用的所有系统资源将被释放。
关于wait在您系统上工作的详细规范请查看您系统的wait(2)手册。这个函数等同于以-1作为参数pid 的值并且没有options参数来调用pcntl_waitpid() 函数。

代码示例:

<?php
$ppid = posix_getpid(); //记录父进程的进程号

for($i = 0; $i < 5; $i++)
{
        $pid = pcntl_fork();

        if ($pid == 0)
        {
                break; //由于子进程也会执行循环的代码,所以让子进程退出循环
        }
}

if ($ppid == posix_getpid())
{
        //父进程循环回收收子进程
        while(($id = pcntl_wait($status)) > 0) //如果没有子进程退出, pcntl_wait 会一直阻塞
        {
                echo "回收子进程:$id, 子进程退出状态值: $status...\n";
        }

        exit("父进程退出 $id....\n"); //当子进程全部结束 pcntl_wait 返回-1
}
else
{
        //子进程退出,会成为僵尸进程
        sleep($i);
        exit($i); 
}


运行结果:

[root@localhost php]# php pcntl.fork.php 
回收子进程:3043, 子进程退出状态值: 0...
回收子进程:3044, 子进程退出状态值: 256...
回收子进程:3045, 子进程退出状态值: 512...
回收子进程:3046, 子进程退出状态值: 768...
回收子进程:3047, 子进程退出状态值: 1024...
父进程退出 -1....


这里只是对PHP多进程编程做了基本的介绍,后面会结合 信号、进程间通信以及守护进程 做更进一步的介绍,欢迎大家关注后续文章。

PHP是世界上最好的语言 That's all :)

相关推荐:

PHP实现系统编程之网络Socket及IO多路复用

위 내용은 PHP는 시스템 프로그래밍을 구현합니다: 다중 프로세스 프로그래밍과 고아 프로세스 및 좀비 프로세스 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
PHP의 초록 클래스 또는 인터페이스에 대한 특성과 언제 특성을 사용 하시겠습니까?PHP의 초록 클래스 또는 인터페이스에 대한 특성과 언제 특성을 사용 하시겠습니까?Apr 10, 2025 am 09:39 AM

PHP에서, 특성은 방법 재사용이 필요하지만 상속에 적합하지 않은 상황에 적합합니다. 1) 특성은 클래스에서 다중 상속의 복잡성을 피할 수 있도록 수많은 방법을 허용합니다. 2) 특성을 사용할 때는 대안과 키워드를 통해 해결할 수있는 방법 충돌에주의를 기울여야합니다. 3) 성능을 최적화하고 코드 유지 보수성을 향상시키기 위해 특성을 과도하게 사용해야하며 단일 책임을 유지해야합니다.

DIC (Dependency Injection Container) 란 무엇이며 PHP에서 사용하는 이유는 무엇입니까?DIC (Dependency Injection Container) 란 무엇이며 PHP에서 사용하는 이유는 무엇입니까?Apr 10, 2025 am 09:38 AM

의존성 주입 컨테이너 (DIC)는 PHP 프로젝트에 사용하기위한 객체 종속성을 관리하고 제공하는 도구입니다. DIC의 주요 이점에는 다음이 포함됩니다. 1. 디커플링, 구성 요소 독립적 인 코드는 유지 관리 및 테스트가 쉽습니다. 2. 유연성, 의존성을 교체 또는 수정하기 쉽습니다. 3. 테스트 가능성, 단위 테스트를 위해 모의 객체를 주입하기에 편리합니다.

SPL SplfixedArray 및 일반 PHP 어레이에 비해 성능 특성을 설명하십시오.SPL SplfixedArray 및 일반 PHP 어레이에 비해 성능 특성을 설명하십시오.Apr 10, 2025 am 09:37 AM

SplfixedArray는 PHP의 고정 크기 배열로, 고성능 및 메모리 사용이 필요한 시나리오에 적합합니다. 1) 동적 조정으로 인한 오버 헤드를 피하기 위해 생성 할 때 크기를 지정해야합니다. 2) C 언어 배열을 기반으로 메모리 및 빠른 액세스 속도를 직접 작동합니다. 3) 대규모 데이터 처리 및 메모리에 민감한 환경에 적합하지만 크기가 고정되어 있으므로주의해서 사용해야합니다.

PHP는 파일 업로드를 어떻게 단단히 처리합니까?PHP는 파일 업로드를 어떻게 단단히 처리합니까?Apr 10, 2025 am 09:37 AM

PHP는 $ \ _ 파일 변수를 통해 파일 업로드를 처리합니다. 보안을 보장하는 방법에는 다음이 포함됩니다. 1. 오류 확인 확인, 2. 파일 유형 및 크기 확인, 3 파일 덮어 쓰기 방지, 4. 파일을 영구 저장소 위치로 이동하십시오.

Null Coalescing 연산자 (??) 및 Null Coalescing 할당 연산자 (?? =)은 무엇입니까?Null Coalescing 연산자 (??) 및 Null Coalescing 할당 연산자 (?? =)은 무엇입니까?Apr 10, 2025 am 09:33 AM

JavaScript에서는 NullCoalescingOperator (??) 및 NullCoalescingAssignmentOperator (?? =)를 사용할 수 있습니다. 1. 2. ??= 변수를 오른쪽 피연산자의 값에 할당하지만 변수가 무효 또는 정의되지 않은 경우에만. 이 연산자는 코드 로직을 단순화하고 가독성과 성능을 향상시킵니다.

CSP (Content Security Policy) 헤더 란 무엇이며 왜 중요한가요?CSP (Content Security Policy) 헤더 란 무엇이며 왜 중요한가요?Apr 09, 2025 am 12:10 AM

CSP는 XSS 공격을 방지하고 리소스로드를 제한하여 웹 사이트 보안을 향상시킬 수 있기 때문에 중요합니다. 1.CSP는 HTTP 응답 헤더의 일부이며 엄격한 정책을 통해 악의적 인 행동을 제한합니다. 2. 기본 사용법은 동일한 원점에서 자원을로드 할 수있는 것입니다. 3. 고급 사용량은 특정 도메인 이름을 스크립트와 스타일로드 할 수 있도록하는 것과 같은보다 세밀한 전략을 설정할 수 있습니다. 4. Content-Security Policy 보고서 전용 헤더를 사용하여 CSP 정책을 디버그하고 최적화하십시오.

HTTP 요청 방법 (Get, Post, Put, Delete 등)이란 무엇이며 언제 각각을 사용해야합니까?HTTP 요청 방법 (Get, Post, Put, Delete 등)이란 무엇이며 언제 각각을 사용해야합니까?Apr 09, 2025 am 12:09 AM

HTTP 요청 방법에는 각각 리소스를 확보, 제출, 업데이트 및 삭제하는 데 사용되는 Get, Post, Put and Delete가 포함됩니다. 1. GET 방법은 리소스를 얻는 데 사용되며 읽기 작업에 적합합니다. 2. 게시물은 데이터를 제출하는 데 사용되며 종종 새로운 리소스를 만드는 데 사용됩니다. 3. PUT 방법은 리소스를 업데이트하는 데 사용되며 완전한 업데이트에 적합합니다. 4. 삭제 방법은 자원을 삭제하는 데 사용되며 삭제 작업에 적합합니다.

HTTPS 란 무엇이며 웹 애플리케이션에 중요한 이유는 무엇입니까?HTTPS 란 무엇이며 웹 애플리케이션에 중요한 이유는 무엇입니까?Apr 09, 2025 am 12:08 AM

HTTPS는 HTTP를 기반으로 보안 계층을 추가하는 프로토콜로, 주로 암호화 된 데이터를 통해 사용자 개인 정보 및 데이터 보안을 보호합니다. 작업 원칙에는 TLS 핸드 셰이크, 인증서 확인 및 암호화 된 커뮤니케이션이 포함됩니다. HTTP를 구현할 때는 인증서 관리, 성능 영향 및 혼합 콘텐츠 문제에주의를 기울여야합니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

WebStorm Mac 버전

WebStorm Mac 버전

유용한 JavaScript 개발 도구

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

SublimeText3 영어 버전

SublimeText3 영어 버전

권장 사항: Win 버전, 코드 프롬프트 지원!

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

DVWA

DVWA

DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는