멀티 프로세스 교착 관리
세마포어와 뮤텍스는 이 포스팅을 보는 본인께서 더 잘 아실 거라 믿는다.
이번에는 php 프로세스 간 세마포어 제어를 다뤄볼 것이다.
인터프리터 주제에 세마포어..!? 라고 생각할 수도 있지만 모든 프로그램은 런타임에 메모리에 적재된 순간부터는 모두 같은 프로세스이기 때문에.. (본인은 php 데몬을 애용하는 편이다. 플랫폼 영향을 안 받기 때문)
php - php간, php - 외 native process 간 등 모든 상황에 공유 자원(e.g. file, I/O, db 등 접근 가능한 모든 대상)의 사용 시 교착(deadlock)에 빠질 수 있다.
그래서 php에서도 세마포어가 된다는 것을 알아보려한다.
소스코드
세마포어를 이용하기 위해선 sem_get() 을 사용해야 하는데 해당 함수의 인자를 살펴보면
sem_get(
int $key,
int $max_acquire = 1,
int $permissions = 0666,
bool $auto_release = true
)
- key
ipc에 등록할 세마포어 키 정보.
shell 에서 ipcs -s (ipc 세마포어만 조회) 명령을 했을때 이미 다른 프로세스가 사용하는 키와 겹치지만 않으면 된다.
물론 동일한 공유 자원의 접근 제어를 하려면 동일한 key를 사용하면 된다.
- max_acquire
세마포어를 동시에 획득할 수 있는 수를 의미한다. I/O가 분명하여 교착이 발생할 수 있는 상황이라면 1을 사용하자.
(대상을 읽기만 하는 등 공유자원의 상태를 변화시키지 않는 경우엔 복수개를 지정해도 된다.)
- permissions
세마포어 권한을 의미한다. 말 그대로 퍼미션이다.
- auto_release
세마포어 락을 자동으로 해제하겠냐라는 의미이다.
<?php
// 세마포어 설정 정보
$key = 0x7593;
$max_acquire = 1;
$permissions = 0666;
$auto_release = true;
// sem_get() 세마포어 설정
if( !($semaphore = sem_get($key, $max_acquire, $permissions, $auto_release)) ) {
echo "sem_get() failed.\n";
return ;
}
// 세마포어 동작
while( true ) {
echo "세마포어 획득 시도\n";
sem_acquire($semaphore);
echo "-> 획득\n";
echo "텍스트 입력: ";
$fp = fopen("php://stdin", "r");
$text = fgets($fp);
fclose($fp);
echo "입력된 텍스트 : {$text} \n";
sem_release($semaphore);
if( strtolower(trim($text, "\n")) == "exit" ) {
echo "끝\n";
break;
}
}
?>
결과
세마포어를 다루는 예제인 만큼 다수의 창을 띄어놓고 결과를 볼것이다.
1. ipcs -s 를 통한 현재 세마포어 정보 확인
- 코드 상에서 지정한 0x7593은 없다. 아직 실행을 안했기 때문.
2. 세마포어를 사용하는 php 파일을 실행한다.
- 실행 후 ipcs -s 를 통해 세마포어 키가 생성됐는지 확인한다.
코드 상에서 지정한 0x7593이 생성된 것을 확인할 수 있다.
3. 동시에 동일한 php를 실행하여 동작을 확인한다.
- 한개의 프로세스에서 세마포어 키를 획득하여 밑에 있는 프로세스에서 획득 시도 상태로 대기하는 것을 확인할 수 있다.
4. 세마포어 획득 중이던 프로세스에서 텍스트 입력을 해서 세마포어를 넘겨보자.
- 기존에 세마포어를 잡고 있던 프로세스에서 텍스트를 입력받고 세마포어를 릴리즈하여 다른 프로세스가 획득 대기중이였다가 바로 키를 획득한 것을 확인할 수 있다.
끝으로 모든 세마포어를 사용하는 프로세스가 종료되었어도 세마포어 키는 남아있을 것이다.
불필요하거나 다른 용도로 사용하기 위해선 세마포어 키를 지우자.
ipcrm -S <key> 를 이용하여 세마포어 정보를 삭제한 것을 확인할 수 있다.
끝.
'IT > web' 카테고리의 다른 글
<frame> Tag (0) | 2022.09.09 |
---|---|
[PHP] 상수를 이용한 다중 텍스트 치환 / const, define to text, constant, preg_match_all (0) | 2022.01.21 |
[PHP] 문자열 앞글자 삭제하기 예제, ltrim/substr 활용 (0) | 2022.01.12 |
[PHP] fileperms을 활용한 파일 탐색과 퍼미션 검사 (0) | 2022.01.06 |
[PHP] readdir을 활용한 파일 목록 읽기 예제, 파일 탐색기 (0) | 2022.01.06 |
댓글