Download presentation
Presentation is loading. Please wait.
1
8장 프로세스
2
8.1 쉘과 프로세스
3
쉘(Shell)이란 무엇인가? 쉘의 역할 쉘은 사용자와 운영체제 사이에 창구 역할을 하는 소프트웨어
명령어 처리기(command processor) 사용자로부터 명령어를 입력받아 이를 처리한다
4
쉘의 실행 절차
5
복합 명령어 명령어 열(command sequence) 명령어 그룹(command group) $ 명령어1; … ; 명령어n
$ date; who; pwd 명령어 그룹(command group) $ (명령어1; … ; 명령어n) $ date; who; pwd > out1.txt $ (date; who; pwd) > out2.txt
6
전면 처리 vs 후면처리 전면 처리 명령어를 입력하면 명령어가 전면에서 실행되며 명령어 실행이 끝 날 때까지 쉘이 기다려 준다. 후면 처리 명령어들을 후면에서 처리하고 전면에서는 다른 작업을 할 수 있 으면 동시에 여러 작업을 수행할 수 있다. $ 명령어 &
7
후면 처리 예 $ fg %작업번호 후면처리 입출력 $ (sleep 100; echo done) & [1] 8320
$ find . -name test.c -print & [2] 8325 $ jobs [1] + Running ( sleep 100; echo done ) [2] - Running find . -name test.c –print $ fg %작업번호 $ fg %1 ( sleep 100; echo done ) 후면처리 입출력 $ find . -name test.c -print > find.txt & $ find . -name test.c -print | mail chang & $ wc < inputfile &
8
프로세스(process) 실행중인 프로그램을 프로세스(process)라고 부른다.
각 프로세스는 유일한 프로세스 번호 PID를 갖는다. ps 명령어를 사용하여 나의 프로세스들을 볼 수 있다. $ ps PID TTY TIME CMD 8695 pts/3 00:00:00 csh 8720 pts/3 00:00:00 ps $ ps u USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND chang pts/3 Ss 11:12 0:00 -csh chang pts/3 R+ 11:15 0:00 ps u
9
프로세스 상태: ps ps [-옵션] 명령어 $ ps -aux (BSD 유닉스) $ ps -ef (시스템 V)
현재 존재하는 프로세스들의 실행 상태를 요약해서 출력 $ ps PID TTY TIME CMD 25435 pts/3 00:00:00 csh 25461 pts/3 00:00:00 ps $ ps -aux (BSD 유닉스) - a: 모든 사용자의 프로세스를 출력 - u: 프로세스에 대한 좀 더 자세한 정보를 출력 - x: 더 이상 제어 터미널을 갖지 않은 프로세스들도 함께 출력 $ ps -ef (시스템 V) - e: 모든 사용자 프로세스 정보를 출력 - f: 프로세스에 대한 좀 더 자세한 정보를 출력
10
sleep sleep 명령어 지정된 시간만큼 실행을 중지한다. $ sleep 초
$ (echo 시작; sleep 5; echo 끝)
11
kill kill 명령어 현재 실행중인 프로세스를 강제로 종료 $ kill [-시그널] 프로세스번호
$ (echo 시작; sleep 5; echo 끝) & 1230 $ kill 1230
12
wait $ wait [프로세스번호] 해당 프로세스 번호를 갖는 자식 프로세스가 종료될 때까지 기다 린다. 프로세스 번호를 지정하지 않으 면 모든 자식 프로세스를 기다린 다. $ (sleep 10; echo 1번 끝) & 1231 $ echo 2번 끝; wait 1231; echo 3번 끝 2번 끝 1번 끝 3번 끝 $ (sleep 10; echo 1번 끝) & $ (sleep 10; echo 2번 끝) & $ echo 3번 끝; wait; echo 4번 끝 3번 끝 1번 끝 2번 끝 4번 끝
13
exit exit 쉘을 종료하고 종료코드(exit code)을 부모 프로세스에 전달 $ exit [종료코드]
14
8.2 프로그램 시작
15
프로그램 실행 시작 exec 시스템 호출 C 시작 루틴(start-up routine)
프로그램을 실행시킨다. C 시작 루틴(start-up routine) main 함수를 호출하면서 명령줄 인수, 환경 변수를 전달 exit( main( argc, argv) ); 실행이 끝나면 반환값을 받아 exit 한다.
16
프로그램 실행 시작
17
명령줄 인수/환경 변수 int main(int argc, char *argv[]); argc : 명령줄 인수의 개수
18
args.c #include <stdio.h> /* 모든 명령줄 인수와 환경 변수를 프린트한다. */ int main(int argc, char *argv[]) { int i; for (i = 0; i < argc; i++) /* 모든 명령줄 인수 프린트 */ printf("argv[%d]: %s \n", i, argv[i]); exit(0); }
19
environ.c #include <stdio.h> /* 모든 명령줄 인수와 환경 변수를 프린트한다. */ int main(int argc, char *argv[]) { char **ptr; extern char **environ; for (ptr = environ; *ptr != 0; ptr++) /* 모든 환경 변수 값 프린트*/ printf("%s \n", *ptr); exit(0); }
20
환경 변수 접근 getenv() 시스템 호출을 사용하여 환경 변수를 하나씩 접근하 는 것도 가능하다.
#include <stdlib.h> char *getenv(const char *name); 환경 변수 name의 값을 반환한다. 해당 변수가 없으면 NULL을 반환한다.
21
printenv.c #include <stdio.h> #include <stdlib.h> /* 환경 변수를 3개 프린트한다. */ int main(int argc, char *argv[]) { char *ptr; ptr = getenv("HOME"); printf("HOME = %s \n", ptr); ptr = getenv("SHELL"); printf("SHELL = %s \n", ptr); ptr = getenv("PATH"); printf("PATH = %s \n", ptr); exit(0); }
22
환경 변수 설정 putenv(), setenv()를 사용하여 특정 환경 변수를 설정한다.
#include <stdlib.h> int putenv(const char *name); name=value 형태의 스트링을 받아서 이를 환경 변수 리스트에 넣어준다. name이 이미 존재하면 원래 값을 새로운 값으로 대체한다. int setenv(const char *name, const char *value, int rewrite); 환경 변수 name의 값을 value로 설정한다. name이 이미 존재하는 경우에는 rewrite 값이 0이 아니면 원래 값을 새로운 값으로 대체하고 rewrite 값이 0이면 그대로 둔다. int unsetenv(const char *name); 환경 변수 name의 값을 지운다.
23
8.3 프로그램 종료
24
프로그램 종료 정상 종료(normal termination) 비정상 종료(abnormal termination)
main() 실행을 마치고 리턴하면 C 시작 루틴은 이 리턴값을 가지 고 exit()을 호출 프로그램 내에서 직접 exit()을 호출 프로그램 내에서 직접 _exit()을 호출 비정상 종료(abnormal termination) abort() 프로세스에 SIGABRT 시그널을 보내어 프로세스를 비정상적으로 종료 시그널에 의한 종료
25
프로그램 종료 exit() 모든 열려진 스트림을 닫고(fclose), 출력 버퍼의 내용을 디스크에 쓰는(fflush) 등의 뒷정리 후 프로세스를 정상적으로 종료 종료 코드(exit code)를 부모 프로세스에게 전달한다. _exit() #include <stdlib.h> void exit(int status); 뒷정리를 한 후 프로세스를 정상적으로 종료시킨다. #include <stdlib.h> void _exit(int status); 뒷정리를 하지 않고 프로세스를 즉시 종료시킨다.
26
atexit() exit 처리기를 등록한다 func exit() 는 exit handler 들을 등록된 역순으로 호출한다
#include <stdlib.h> void atexit(void (*func)(void)); returns: 0 if OK, nonzero on error exit 처리기를 등록한다 프로세스당 32개까지 func exit 처리기 함수 포인터(이름) exit() 는 exit handler 들을 등록된 역순으로 호출한다 © 숙대 창병모
27
C 프로그램 시작 및 종료 …… _exit user function exit handler _exit exit main
call return return call exit (does not return) …… _exit call return main function exit (does not return) exit function user process exit handler return call call return (does not return) exit C start-up routine standard I/O cleanup _exit exec kernel © 숙대 창병모
28
exit 처리기 예 1 #include <stdio.h>
2 static void my_exit1(void), my_exit2(void); 4 int main(void) { 5 if (atexit(exit_handler1) != 0) 6 perror("exit_handler1 등록할 수 없음"); 7 if (atexit(exit_handler2) != 0) 8 perror("exit_handler2 등록할 수 없음"); 9 printf("main 끝 \n"); 10 exit(0); 11 } 12 13 static void exit_handler1(void) { 14 printf("첫 번째 exit 처리기\n"); 15 } 16 17 static void exit_handler2(void) { 18 printf("두 번째 exit 처리기\n"); 19 } © 숙대 창병모
29
8.4 프로세스 ID
30
프로세스 ID 각 프로세스는 프로세스를 구별하는 번호인 프로세스 ID를 갖는다.
각 프로세스는 자신을 생성해준 부모 프로세스가 있다. int getpid( ); 프로세스의 ID를 리턴한다. int getppid( ); 부모 프로세스의 ID를 리턴한다.
31
pid.c 1 #include <stdio.h> 2 3 /* 프로세스 번호를 출력한다. */ 4 int main() 5 { 6 int pid; 7 printf("나의 프로세스 번호 : [%d] \n", getpid()); 8 printf("내 부모 프로세스 번호 : [%d] \n", getppid()); 9 }
32
프로세스의 사용자 ID 프로세스는 프로세스 ID 외에 프로세스의 사용자 ID와 그룹 ID를 갖는다.
프로세스가 수행할 수 있는 연산을 결정하는 데 사용된다.
33
프로세스의 사용자 ID 프로세스의 실제 사용자 ID(real user ID)
예를 들어 chang이라는 사용자 ID로 로그인하여 어떤 프로그램을 실행시키면 그 프로세스의 실제 사용자 ID는 chang이 된다. 프로세스의 유효 사용자 ID(effective user ID) 현재 유효한 사용자 ID로 새로 파일을 만들 때나 파일에 대한 접근 권한을 검사할 때 주로 사용된다. 보통 유효 사용자 ID와 실제 사용자 ID는 특별한 실행파일을 실행 할 때를 제외하고는 동일하다.
34
프로세스의 사용자 ID 프로세스의 실제/유효 사용자 ID 반환 프로세스의 실제/유효 그룹 ID 반환
#include <sys/types.h> #include <unistd.h> uid_t getuid( ); 프로세스의 실제 사용자 ID를 반환한다. uid_t geteuid( ); 프로세스의 유효 사용자 ID를 반환한다. uid_t getgid( ); 프로세스의 실제 그룹 ID를 반환한다. uid_t getegid( ); 프로세스의 유효 그룹 ID를 반환한다.
35
프로세스의 사용자 ID 프로세스의 실제/유효 사용자 ID 변경 프로세스의 실제/유효 그룹 ID 변경
#include <sys/types.h> #include <unistd.h> int setuid(uid_t uid); 프로세스의 실제 사용자 ID를 uid로 변경한다. int seteuid(uid_t uid); 프로세스의 유효 사용자 ID를 uid로 변경한다. int setgid(gid_t gid); 프로세스의 실제 그룹 ID를 gid로 변경한다. int setegid(gid_t gid); 프로세스의 유효 그룹 ID를 gid로 변경한다.
36
uid.c #include <stdio.h> #include <pwd.h> #include <grp.h> /* 사용자 ID를 출력한다. */ int main() { int pid; printf("나의 실제 사용자 ID : %d(%s) \n", getuid(), getpwuid(getuid())->pw_name); printf("나의 유효 사용자 ID : %d(%s) \n", geteuid(), getpwuid(geteuid())->pw_name); printf("나의 실제 그룹 ID : %d(%s) \n", getgid(), getgrgid(getgid())->gr_name); printf("나의 유효 그룹 ID : %d(%s) \n", getegid(), getgrgid(getegid())->gr_name); }
37
set-user-id 실행파일 특별한 실행권한 set-user-id(set user ID upon execution)
이 프로세스는 실행되는 동안 그 파일의 소유자 권한을 갖게 됨. 예 : /usr/bin/passwd 명령어 set-user-id 실행권한이 설정된 실행파일이며 소유자는 root 일반 사용자가 이 파일을 실행하게 되면 이 프로세스의 유효 사용 자 ID는 root가 됨. /etc/passwd처럼 root만 수정할 수 있는 파일의 접근 및 수정 가능
38
set-user-id 실행파일 set-user-id 실행권한은 심볼릭 모드로 's'로 표시 set-uid 실행권한 설정
$ ls –asl /bin/su /usr/bin/passwd 32 -rwsr-xr-x. 1 root root :50 /bin/su 28 -rwsr-xr-x. 1 root root :00 /usr/bin/passwd set-uid 실행권한 설정 $ chmod 4755 file1 set-gid 실행권한 설정 $ chmod 2755 file1
39
8.5 프로세스 구조
40
프로세스 프로세스는 실행중인 프로그램이다. 프로그램 실행을 위해서는 프로세스 이미지(구조)는 메모리 내의 프로세스 레이아웃
프로그램의 코드, 데이터, 스택, 힙, U-영역 등이 필요하다. 프로세스 이미지(구조)는 메모리 내의 프로세스 레이아웃 프로그램 자체가 프로세스는 아니다 !
41
프로세스 구조 프로세스 구조
42
프로세스 구조 텍스트(text) 데이터 (data) 힙(heap) 스택(stack area) U-영역(user-area)
프로세스가 실행하는 실행코드를 저장하는 영역이다. 데이터 (data) 전역 변수(global variable) 및 정적 변수(static variable)를 위한 메모리 영역이다. 힙(heap) 동적 메모리 할당을 위한 영역이다. C 언어의 malloc 함수를 호출하면 이 영역에서 동적으로 메모리를 할당해준다. 스택(stack area) 함수 호출을 구현하기 위한 실행시간 스택(runtime stack)을 위한 영역으로 활성 레코드(activation record)가 저장된다. U-영역(user-area) 열린 파일 디스크립터, 현재 작업 디렉터리 등과 같은 프로세스의 정보를 저장하는 영역이다.
43
핵심 개념 프로세스는 실행중인 프로그램이다. 쉘은 사용자와 운영체제 사이에 창구 역할을 하는 소프트웨어로 사 용자로부터 명령어를 입력받아 이를 처리하는 명령어 처리기 역할을 한다. 프로그램이 실행되면 프로그램의 시작 루틴에게 명령줄 인수와 환경 변수가 전달된다. exit()는 뒷정리를 한 후 프로세스를 정상적으로 종료시키고 _exit()는 뒷정리를 하지 않고 프로세스를 즉시 종료시킨다. exit 처리기는 exit()에 의한 프로세스 종료 과정에서 자동으로 수행된 다. 각 프로세스는 프로세스 ID를 갖는다. 각 프로세스는 자신을 생성해 준 부모 프로세스가 있다. 각 프로세스는 실제 사용자 ID와 유효 사용자 ID를 가지며 실제 그룹 ID와 유효 그룹 ID를 갖는다. 프로세스 이미지는 텍스트(코드), 데이터, 힙, 스택 등으로 구성된다.
Similar presentations