개발자 공부하기/운영체제

[Swift] Process 클래스로 다른 Application 실행 / 프로세스 제어하기

스윗 앨리스 2020. 9. 29. 11:19
프로세스 제어를 위한 시스템 API
지난번 프로세스 제어를 위한 시스템 API 내용을 먼저 정리하자.
프로세스 관련 지식이 부족하다면,

[운영체제] 프로세스의 개념 정복하기
[운영체제] 프로세스의 생성과 종료 / 요약 정리

 

1. fork()

부모 프로세스에서 호출 되면, 자식 프로세스는 독립적인 메모리 공간에 부모와 동일한 내용이 복사된다.

부모의 PCB 내용까지 복제되어 자식 프로세스는 fork() 함수부터 다시 수행된다.

때문에 fork()를 부모 프로세스에서 호출하면 return을 부모에게서 한번, 자식에게서 한번

이렇게 2번 받게 된다는 것이 중요하다.

 

 fork()의 return
부모 프로세스새로 생성된 자식 프로세스의 PID
자식 프로세스0
시스템 호출 실 패 시-1

 

2. wait()

부모 프로세스에서 호출 시 자식 프로세스 중 하나가 종료될 때까지 대기한다.

 

3. exec()

새로운 프로그램을 위한 내용으로 현재 프로세스의 메모리 내용을 교체한다.

기존에 열린 파일은 커널에서 관리되는 부분이므로 교체되지 않고, 새로운 프로그램에게 상속된다.

exec()가 성공하는 경우에 리턴은 없다.

=> 정확히 말하면, 프로그램이 완전히 교체되는 것이기 때문에 리턴을 할 수 없는 것이다.

 

일반적인 exec() 함수의 사용법

부모 프로세스에서 fork() 하여 생긴 자식 프로세스에서 exec()를 호출함으로서 부모 프로세스로부터 상속받은 내용을 새로운 프로그램으로 덮어쓴다.

부모 프로세스는 wait()를 사용하여 자식 프로세스가 종료되기를 기다린다.


Swift 를 이용하여 프로세스 제어하기

Swift 에서는 다른 프로그램을 실행시키고, 모니터할 수 있는 Process class를 제공하고 있다.

위의 시스템 API (fork(), wait(), exec()) 를 직접 호출해서 할수도 있을텐데, 

let pid = fork() 해봤더니 에러가 뜬다. 이거는 나중에 공부해서 내용을 업데이트 해야겠다.

 

 

 Process 클래스

 

 

* Process Class : https://developer.apple.com/documentation/foundation/process

 

Apple 문서에 설명에서 보면, default로 부모 프로세스의 환경을 상속 받고 부모 프로세스와는 메모리 공간을 공유하는 것은 아니다.

라고 되어있다.

정확한 내부로직은 모르겠지만 부모 프로세스를 fork() 하고, 새로운 프로그램을 exec() 하는 것 같다.

 

아래는 Safari 앱을 Process Class를 이용하여 실행시키는 코드

import Foundation

// Parent Process
let parentPID = getpid()

// Child Process
let child = Process.init()
child.executableURL = URL(fileURLWithPath: "/Applications/Safari.app/Contents/MacOS/Safari")
child.arguments = []
child.launch()

NSLog("Parent PID: %d, Child PID: %d", parentPID, child.processIdentifier)

child.waitUntilExit()
NSLog("Child exit status is %d", child.terminationStatus)

자식 프로세스 Launch() 후 두개의 프로세스 ID가 서로 다른지를 확인해보았다. (첫번째 NSLog)

자식 프로세스가 종료될 때까지 부모 프로세스는 WaitUntilExit() 으로 기다리도록 했다.

 

런타임에서 실행된 Safari를 종료시키니 waitUntilExit() 다음 코드인 NSLog가 실행됐다.

자식 프로세스가 어떻게 종료되었는지 Status 값 찍고 프로그램 종료.

 

실행 결과

 

 

Parent PID와 Child PID가 다른 것 확인.

Child 프로세스 termination status 는 0으로 정상 종료되었다.