posted by 구름너머 2006. 8. 17. 09:40

10. 프로세스와 시그널 프로세스는 무엇인가?

수행되는 프로그램.(시스템 자원을 요구하는 하나의 스레드와 주소공간)

프로세스의 구조

각각의 프로세스는 프로세스 식별자로 구분한다.

grep 명령에 의해 수행되는 프로그램 코드는 디스크상에 파일로 저장되어 있다가 읽기만 가능한 메모리상으로 올라온다.

시스템 라이브러리도 공유된다.

프로세스는 함수에서 사용되는 지역변수, 함수의 호출과 반환을 제어하기 위한 목적으로 자신만의 스택을 가지고 있다. 또한 자신의 사용목으로 환경변수를 포함하는 환경영역을 가지고 있다.

  • 프로세스 테이블

현재 적재된 모든 프로세스를 나타내는 데이터구조가 프로세스 테이블이다.

PID, 터미널형태, 프로세스 상태와 명령등으로 구성되고, ps명령에 의해 볼 수 있다.

보통은 256 프로세스로 제한이 되어 있다. 그러나 최근엔...(?)

  • 프로세스 살펴보기

ps 명령으로 현재 수행되고 있는 프로세스를 살펴볼 수 있다.

-x 옵션은 전체프로세스의 상황을 보여주며, -a 옵션은 모든 사용자가 수행하고 있는 프로세스 정보를 보여준다. 그 외에는 man을 참고하자.

  • 시스템 프로세스

$ ps -ax

init 는 모든 프로세스의 조상이며, 다른 시스템 프로세스는 init에서 파생된다.

  • 프로세스 스케줄링

상태(STAT)가 S이면 Sleep 상태이며, R이면 다른 프로세스가 작업을 마치기를 기다리지 않고 있거나 입출력이 완료되기를 기다리고 있는 상태라는 뜻이다.

유닉스 시스템은 다음 시간에 어떤 프로세스를 할당할 지를 결정하기 위해서 프로세스 스케줄러를 사용한다. 이것은 프로세스의 우선순위에 기반한다.

nice 프로그램은 프로그램의 우선순위를 변경할 수 있고, renice는 해당 프로세스의 우선순위를 10만큼 감소시킬 수 있다.

우선순위의 기본은 0이며 높은 우선순위는 음수값을 낮은 우선순위는 양수값을 갖는다. 현재 활성화된 프로세스의 우선순위값은 ps -l 로 볼 수 있다.

 

새로운 프로세스를 수행하기

system함수는 하나의 프로그램 내부에서 다른 프로그램을 실행시킨다.

system함수는 해당명령이 종료할 때 까지 기다린다. 즉, 호출한 프로세스가 끝날 때까지 기다린다. system함수가 다른 명령을 호출한 즉시 리턴되도록 하려면 끝에 '&'를 붙여 백그라운드로 실행시키도록 한다.

system함수는 쉘상에서 'sh -c string' 와 같다.

[예제. p397]

  • 프로세스 이미지의 대체

exec류의 함수들은 현재의 프로세스를 주어진 인자에 따라 생성되는 또 다른 프로세스로 대체한다.

함수는 exec, execlp, execle, execv, execvp, execve 등이 있다.

[예제. p400] execlp 호출

  • 프로세스 이미지의 복사

fork를 사용하면 새로운 프로세스를 만들 수 있다.

생성된 자식 프로세스는 부모 프로세스의 데이터 공간(변수), 열려진 파일 기술자, 디렉토리 복사본 등을 보유한다.

[예제. 10.402]

  • 프로세스를 기다리기

wait를 사용하면 부모 프로세스는 자식 프로세스가 종료하기를 기다린다

[예제. 404]

  • 좀비 프로세스

자식 프로세스가 종료하더라도, 부모 프로세스가 정상적으로 종료하거나 wait를 호출할때 까지 자식은 완전히 죽지 않고 시스템에서 잔류한다.

이럴경우 자식은 좀비 프로세스로 바뀐다.

[예제. p406]

waitpad 시스템 호출은 특정한 자식프로세스가 종료하기를 기다리는데 사용할 수 있다.

  • 입력과 출력의 리다이렉션

[예제. p408]

  • 스레드

스레드는 '중량' 프로세스와 대비되는 '경량' 프로세스라고 할 수 있다.

프로세스는 서로 영향을 미치지 않지만 스레드는 다른 스레드에게 치명적인 영향을 줄 수 있다.

시그널

시그널은 어떠한 조건에 대응하여 유닉스 시스템이 발생시키는 일종의 사건이다.

시그널은 쉘이나 시그널을 발생시키는 터미널 처리기에 의해 발생한다.

하나의 프로세스에서 다른 프로세스에게 정보를 전달하거나, 행동을 변경시키기 위해 시그널을 보낼 수 있다.

시그널은 생성되거나 포착되거나 무시될 수 있다.

시그널(을 받는) 함수는 signal이며 sig와 func의 두개의 매개변수를 받는다.

sig에는 포착하거나 무시할 시그널을 명시하고, func는 해당 시그널을 받을 때 호출할 함수이다. func함수는 하나의 int인자를 가져야 하며 형은 void이어야 한다. func함수는 이전의 sig시그널에 설정된 함수를 반환하거나 SIG_IGN(시그널무시), 또는 SIG_DEL(기본액션저장)을 반환해야 한다.

[예제. p413]

  • 시그널을 보내기

프로세스는 raise를 호출하여 자기 자신에게 시그널을 보낼 수 있다.

하나의 프로세스는 kill 호출을 사용하여 다른 프로세스에게 시그널을 보낼 수 있다.

시그널은 사용자에게 유용한 알람시계를 제공하는데, alarm 호출은 해당 프로세스가 SIGALRM시그널을 예약하는데 사용될 수 있다.

[예제. p416] 알람시계..

getpid() - 현재프로세스의 PID

getppid() - 부모프로세스의 PID

pause() - 시그널이 발생할 때까지 프로그램 실행 중단

  • 튼튼한 시그널 인터페이스

시그널을 포착해서 지정한 함수를 실행중일 때 같은 시그널이 또 발생한다면 결과는 예측하기 어렵다. 이것이 임계 타이밍의 문제이며 프로그래머가 해결해야 한다.

그래서 좀더 튼튼한 새로운 프로그래밍 인터페이스로서 sigaction 을 추천한다.

sigaction 은 시그널이 발생해서 해당 함수가 실행되는 동안 그 시그널을 블럭시킨다.

sigaction 함수는 구조체로 sigaction을 포함하고 있는데, 매개변수로 시그널 sig가 포착되었을 때 실행되는 액션을 정의한다.

[예제. p419] sigaction으로 SIGINT를 처리한다.

  • 시그널 집합

signal.h 에는 'sigset_t'형과 시그널 집합을 처리하는 함수들이 정의되어 있다.

sigemptyset - 시그널 집합을 텅비게 한다.

sigfillset - 정의된 모든 시그널을 시그널 집합에 포함하도록 설정한다.

sigaddset, sigdelset - 지정한 시그널(signo)을 시그널 집합에 추가하거나 제거한다.

sigismember - 지정한 시그널이 시그널 집합의 멤버인지 검사한다.

sigprocmask - 프로세스의 시그널 마스크를 설정하거나 검사한다.

sigpending - 현재 블록되어 미결인 채로 남아있는 시그널을 검사한다.

sigsuspend - 프로세스를 시그널 집합 중 하나가 도착할 때까지 수행을 중단시킨다.

sigaction 플래그

sigaction에서 사용되는 sigaction구조체의 sa_flags 필드는 시그널의 행동을 수정하기 위해 다음과 같은 값을 포함할 수 있다.

-> SA_NOCLDSTOP, SA_RESETHAND, SA_RESTART, SA_NODEFER

  • 공통적인 시그널

유닉스 프로그램에서 전형적으로 필요로 하는 시그널들은 다음과 같다.

존재하는 시그널의 목록

이름

signal - 존재하는 시그널의 목록

설명

리눅스는 아래 나열된 시그널을 지원한다. 몇몇 개의 시그널 번호는 아키텍쳐 의존적이다.

먼저 POSIX.1에서 설명하는 시그널이다.

시그널

번호

행동

설명

SIGINT

2

A

키보드로부터의 인터럽트(interrupt) 시그널

SIGQUIT

3

C

키보드로부터의 종료(quit) 시그널

SIGILL

4

C

잘못된 명령어(Illegal Instruction)

SIGABRT

6

C

abort(3)로부터의 중단(abort) 시그널

SIGFPE

8

C

부동 소수점 예외(exception)

SIGKILL

9

AEF

kill 시그널

SIGSEGV

11

C

잘못된 메모리 참조

SIGPIPE

13

A

깨진 파이프: 수신자가 없는 파이프에 쓰기

SIGALRM

14

A

alarm(2)으로부터의 타이머 시그널

SIGTERM

15

A

종료(termination) 시그널

SIGUSR1

30,10,16

A

사용자 정의 시그널 1

SIGUSR2

31,12,17

A

사용자 정의 시그널 2

SIGCHLD

20,17,18

B

자식 프로세스가 중단 또는 종료

SIGCONT

19,18,25

중단되었다면 재개(continue)

SIGSTOP

17,19,23

DEF

프로세스 중단

SIGTSTP

18,20,24

D

터미널에서의 중단 시그널

SIGTTIN

21,21,26

D

백그라운드 프로세스에 대한 터미널 입력

SIGTTOU

22,22,27

D

백그라운드 프로세스에 대한 터미널 출력

다음은 POSIX.1의 시그널은 아니지만 SUSv2에서 설명하고 있는 것이다.

시그널

번호

행동

설명

SIGPOLL

A

폴링(poll) 이벤트 (Sys V). SIGIO와 같다.

SIGPROF

27,27,29

A

프로파일링(profiling) 타이머 시그널

SIGSYS

12,-,12

C

루틴에 잘못된 인자 (SVID)

SIGTRAP

5

C

trace/breakpoint 트랩

SIGURG

16,23,21

B

소켓에 대한 긴급(urgent) 상황 (4.2 BSD)

SIGVTALRM

26,26,28

가상 알람 클럭 (4.2 BSD)

SIGXCPU

24,24,30

C

CPU 시간 제한 초과 (4.2 BSD)

SIGXFSZ

25,25,31

C

파일 크기 제한 초과 (4.2 BSD)

(SIGSYS, SIGXCPU, SIGXFSZ와 몇몇 아키텍쳐에서는 SIGBUS의 기본 행동은 SUSv2에서 C(종료와 코어 덤프)로 나와있지만 현재 리눅스(2.3.27)에서는A(종료)이다)

다음은 여러 가지 다른 시그널.

시그널

번호

행동

설명

SIGEMT

7,-,7

SIGSTKFLT

-,16,-

보조프로세서의 스택 오류

SIGIO

23,29,22

A

현재 I/O가 가능 (4.2 BSD)

SIGCLD

-,-,18

SIGCHLD와 같다.

SIGPWR

29,30,19

A

전원 문제 (System V)

SIGINFO

29,-,-

SIGPWR와 같다.

SIGLOST

-,-,-

A

파일 락(lock) 손실

SIGWINCH

28,28,20

B

윈도우 크기 변경 시그널 (4.3 BSD, Sun)

SIGUNUSED

-,31,-

A

사용되지 않는 시그널 (SIGSYS가될 것이다)

(여기서 -는 시그널이 없음을 나타낸다. 세 가지 값이 있다. 첫번째 것은 대개 alpha sparc에서, 중간의 것은 i386, ppc sh에서, 마지막 것은 mips에서 유효한 값이다. 29번 시그널은 alpha에서는 SIGINFO / SIGPWR이지만 sparc에서는 SIGLOST이다.)

"행동" 컬럼의 문자는 다음과 같은 의미이다:

A 기본 행동이 프로세스를 종료하는 것이다.

B 기본 행동이 시그널을 무시하는 것이다.

C 기본 행동이 프로세스를 종료하고 코어를 덤프한다.

D 기본 행동이 프로세스를 멈추는 것이다.

E 핸들러를 둘 수 없는 시그널이다.

F 무시할 수 없는 시그널이다.

호환

POSIX.1

버그: SIGIOSIGLOST는 같은 값을 갖는다. 후자는 커널 소스에서 주석 처리되었지만, 몇몇 소프트웨어의 프로세스는 여전히 29번 시그널을 SIGLOST로 생각한다.

'UNIX' 카테고리의 다른 글

간단한 network 명령외... for DOS and UNIX  (0) 2006.08.31
[unix]압축-compress 사용법  (0) 2006.08.22
안전한 유닉스 프로그래밍을 위한 지침서 V.0.7  (0) 2006.08.17
Dynamic SQL의 사용  (1) 2006.08.11
UNIX 고급  (0) 2006.08.11