#!/usr/bin/ruby

# 프로세스와 스레드


## 프로세스

=begin

* gid : 그룹 아이디
* pid : 프로세스 아이디
* ppid : 부모 프로세스 아이디
* uid : 사용자 아이디

* abort : 현재 프로세스를 즉시 종료합니다.
* daemon : 프로세스를 백그라운드 프로세스로 전환시킵니다.
* at_exit
* exit : 프로세스를 종료시키고, SystemExit 예외를 던집니다.
* exit! : 프로세스를 즉시 종료시킵니다.

=end

exec('ls -al') # 현재 프로세스가 새로운 프로세스로 대체됩니다.




## 서브 프로세스

=begin

* detach : 자식 프로세스가 좀비 프로세스가 되지 않도록 합니다.
* fork : 자식 프로세스를 만듭니다.
* kill : 프로세스에 신호를 보냅니다.
* spawn : 자식 프로세스를 만듭니다.
* wait, waitpid : 자식 프로세스가 종료될 때까지 기다립니다.
* wait2, waitpid2
* waitall : 모든 자식 프로세스가 종료될 때까지 기다립니다.

=end

o = `ls -al` # 쉘 명령을 실행합니다. 표준 출력의 결과가 반환됩니다.
puts o


fork do # 현재 프로세스를 두 개로 나눕니다. 부모 프로세스는 wait()이나 detach()를 사용해야할 수도 있습니다.
  # do something
end

pid = spawn('pwd') # 자식 프로세스를 만들고, 즉시 프로세스 아이디를 반환합니다.

system('pwd') # 자식 프로세스를 만들고, 실행 결과를 true/false/nil 중 하나로 반환합니다.




### Shellwords

require 'shellwords'

argv = Shellwords.split('one, two, three') # 문자열을 쉘 명령에 쓰기 좋은 형태의 배열로 쪼갭니다.
argv = 'one, two, three'.shellsplit

filename = Shellwords.escape("it's a file.txt") # 특수문자를 처리합니다.
filename = "it's a file.txt".shellescape

dir = "My Documents"
argv = %W[ls -lta -- #{dir}]
system(argv.shelljoin + " | less") # 배열을 문자열로 합칩니다.




## 스레드

thread = Thread.new {
  # do something
  "Job done."
}
thread.join # 스레드가 종료될 떄까지 메인 스레드를 멈춥니다.A
thread.value # 스레드의 마지막 값을 확인할 수 있습니다.

Thread.kill(thread) # 스레드를 종료시킵니다.
thread.exit

thread.status # 스레드의 동작 상태를 확인할 수 있습니다.
thread.alive?
thread.stop?

Thread.current # 현재 스레드를 반환합니다.
Thread.main
Thread.list


sleep(1.2) # 1.2초 동안 스레드를 대기시킵니다.






END{
  # https://ruby-doc.org/3.3.0/Kernel.html
  # https://ruby-doc.org/3.3.0/stdlibs/shellwords/Shellwords.html

  # https://ruby-doc.org/3.3.0/Process.html
  # https://ruby-doc.org/3.3.0/Thread.html
}
