Presentation is loading. Please wait.

Presentation is loading. Please wait.

12. 시스템 프로그래밍 (System Programming)

Similar presentations


Presentation on theme: "12. 시스템 프로그래밍 (System Programming)"— Presentation transcript:

1 12. 시스템 프로그래밍 (System Programming)
화면이 이상하게도 움직이지 않을 때 ^Q(Control+Q)를 눌러보자. 우연히 ^S가 눌려져서 화면표시가 중단되었는지 모른다. 무엇인가 움직여야 할 때 움직이지 않는다면 프로그램이나 데이터에 아무런 손상을 입히지 않는 ^Q를 눌러 보자. Unix/Linux 버전 알아보기: $ uname -a 기말시험 2010년 12월 13일(월) 6:30pm

2 소개 에러 처리 정규 파일 관리 Process Management Signal Pipe Socket perror()
정규 파일 생성, 열기, 닫기, 읽기, 쓰기 Process Management 프로세스의 복사, 차별화, 일시중지, 종료 Signal 시그널 기능 Pipe 파이프를 통한 프로세스간 상호 통신 Socket 소켓을 통한 프로세스간 상호 통신 시스템 프로그래밍

3 에러처리 Library Routine: void perror (char* str) 에러처리 : PERROR()
시스템 호출의 에러를 다루기 위함 errno 가장 최근의 시스템 호출 에러의 숫자 코드를 저장하고 있는 전역 변수 시스템 호출 에러 발생시 원인과 관련된 숫자 코드로 설정됨 프로세스 생성시엔 0으로, 존재하지 않는 파일을 open할 경우 2로 설정 perror() 시스템 호출 에러를 서술하는 서브루틴 현재 errno의 값을 영문 설명으로 변환 동작 (예) showErrno.c Library Routine: void perror (char* str)  perror( )는 화면에 문자열 str을 표시  콜론과 시스템 호출 에러에 대한 설명을 표시  에러가 없으면 문자열 “Error 0”을 표시 시스템 프로그래밍

4 정규 파일 관리 파일 관리 시스템 호출의 4가지 부분 파일 관리 시스템 호출  유닉스 파일과 파일 기술자의 주요 개념
 기본적 파일 관리 시스템 호출  진보된 시스템 호출  여러 부분적인 소스 코드를 사용하는 나머지 파일 시스템 호출 파일 관리 시스템 호출 정규 파일, 디렉토리, 특수 파일을 다룸 특수파일은 다음을 포함한다. - 디스크에 기반한 파일 - 터미널 - 프린터 - 파이프나 소켓 같은 프로세스간 상호 통신 기능 시스템 프로그래밍

5 정규 파일 관리 파일 기술자(file descriptor) int fd; /* 파일 기술자 */ …
Solaris 10: /usr/include/sys/file.h 및 vnode.h 참조 (struct vnode /* in vnode.h 180 line) GNU/Linux: /home/4.4BSD-Lite/usr/src/sys/sys/filedesc.h 참조 Fedora 13: /usr/src/kernels/ fc13-i686.PAE/include/linux/file.h 및 fs.h참조 struct file /* in file.h */ struct address_space /* in fs.h 624 line */ struct inode /* in fs.h 725 line */ 사용 예제 int fd; /* 파일 기술자 */ fd = open (fileName, …) /* 파일 열기, 파일기술자를 반환 */ if (fd = = -1) { /* 에러 조건 처리 */ } fcnt1 (fd, …); /* 필요시 입출력 플래그 설정 */ read (fd, …); /* 파일 읽기 */ write (fd, …); /* 파일 쓰기 */ ... lseek (fd, …); /* 파일 내 찾기 */ close (fd) ; /* 파일 닫기, 파일 기술자를 풀어준다 */ 시스템 프로그래밍

6 정규 파일 관리 파일 기술자는 0으로부터 시작해서 연속적으로 번호가 부여됨
파일 기술자는 0으로부터 시작해서 연속적으로 번호가 부여됨 각 프로세스는 User File Descriptor Table 가짐 User File Descriptor Table -> File Table -> Inode Table 모든 프로세스는 일반적으로 한 순간에 20개까지 열린 파일을 보유할 수 있음 ( 0<= fd <= 19) 파일 기술자의 처음 3개 값은 특수한 의미 /usr/include/unistfd.h 참조 /usr/src/kernels/ fc11.i686.PAE/include/unistfd.h 참조 예) printf( ) 는 항상 파일 기술자 1을 사용해서 출력 scanf( ) 는 항상 파일 기술자 0을 사용해서 입력 의미 표준 입력 1 표준 출력 2 표준 에러 시스템 프로그래밍

7 정규 파일 관리 fd1 파일 fd2 fd3 하나의 파일이 여러 번 열릴 경우 여러 개의 파일 기술자를 갖게 됨
시스템 프로그래밍

8 정규 파일 관리 파일 기술자가 갖는 개별적 집합들 (예) reverse.c 파일 포인터 (Inode 인덱스)
읽기, 쓰기를 수행하고 있는 파일 내의 옵셋(offset)을 기록 파일 기술자가 만들어질 때 default로 파일 내의 옵셋 0(첫번째 문자)에 위치 프로세스가 읽기, 쓰기를 할 때 함께 갱신됨 프로세스가 exec를 수행할 때 파일 기술자가 자동적으로 닫혀야 하는지를 나타내는 플래그 파일로의 모든 출력이 파일의 끝에 추가 되어야 하는 지를 나타내는 플래그 특별한 파일인 경우 다음 값들이 추가됨 (예) 파이프나 소켓의 경우 파일이 아무런 입력도 포함하지 않을 경우 프로세스가 입력을 막아야 하는지를 나타내는 플래그 파일에 입력이 있다면 SIGIO 시그널이 전송되어야 하는 프로세스 id 혹은 프로세스 그룹을 나타내는 숫자 (예) reverse.c 시스템 프로그래밍

9 정규 파일 관리 기본적인 입출력 시스템 호출 기능 이 름 기 능 open 파일을 열고 생성 read
이 름 기 능 open 파일을 열고 생성 read 파일로부터 바이트들을 버퍼로 읽어들임 write 버퍼로부터 바이트들을 파일에 씀 lseek 파일내의 특별한 옵셋으로 이동 close 파일을 닫음 unlink 파일을 삭제 시스템 프로그래밍

10 정규 파일 관리 파일 열기 : open( ) 임의의 파일에 접근하거나 파일을 생성하기 위함 성공하면 음수가 아닌 fd 값 반환, 실패하면 -1을 반환 동작 fileName : 절대 or 상대 경로명 mode : 읽기/쓰기 플래그와 0개 혹은 그 이상의 다른 플래그를 비트 연산 or를 수행한 값 permission : 허가권 플래그의 값을 코드화한 수 오직 파일 생성시에만 제공되어야함 System call: int open (char* filename, int mode, [int permission]) 시스템 프로그래밍

11 정규 파일 관리 읽기 쓰기 플래그 그 외의 플래그 O_RDONLY : 읽기 전용으로 열기
O_WRONLY : 쓰기 전용으로 열기 O_RDWR : 읽기와 쓰기를 위해 열기 그 외의 플래그 O_APPEND : write( ) 이전에 파일 포인터를 파일의 끝에 위치시킴 O_CREAT : 파일이 존재하지 않으면 파일을 생성하고 소유자 id를 프로세스의 유화 UID로 설정, 그룹 id를 파일이 생성된 디렉토리의 그룹 id로 설정 O_EXCL : O_CREAT가 설정되고 파일이 존재하면 open( )은 실패 O_NONBLOCK : (= O_NDELAY) 명명된 파이프에 대해서만 동작, 읽기 전용 파일 열기의 즉시 복귀, 읽기 끝이 열려있지 않다면 쓰기 전용 파일 열기는 실패 이 플래그가 설정되어 있지 않으면 읽기 전용 파일 열기나 쓰기 전용 파일 열기는 다른 끝이 열릴 때까지 방해 받게됨 O_TRUNC : 파일이 존재하면 그 길이가 0이 되도록 자름 시스템 프로그래밍

12 정규 파일 관리 sprintf (tmpName, “.rev.%d”, getid( ) ); /* 임의의 이름*/
파일의 생성 O_CREAT 플래그 사용 초기 허가권 플래그 설정은 8진수 값으로 제공 사용 예제 getid( ) 함수 : 유일성이 보증되는 프로세스 id 번호(PID)를 반환하는 시스템 호출, 고유한 임시 파일 이름 생성 존재하는 파일 열기 단지 모드 플래그들만 명시 그 밖의 열기 플래그 O_NONBLOCK : 파이프 및 소켓과 함께 사용 sprintf (tmpName, “.rev.%d”, getid( ) ); /* 임의의 이름*/ /* 입력의 복사를 저장할 임시 파일 생성 */ tmpfd = open (tmpName, O_CREAT | O_RDWR, 0600); if (tmpfd == -1) fatalError ( ); fd = open (fileName, O_RDONLY); if (fd == -1) fatalError ( ); 시스템 프로그래밍

13 정규 파일 관리 파일 읽기 : read( ) 일정한 크기로 입력을 읽어서 처리
성공하면 읽혀진 바이트 수 반환, 실패하면 -1 반환 마지막 바이트가 읽혀진 후면 0(파일의 끝)을 반환 동작 read( ) : 파일 기술자 fd 에 의해 참조된 파일에서 count 개수의 문자를 읽어 버퍼 buf 에 복사, 현재 파일 위치에서 바이트가 읽혀진 후 파일 위치가 변경됨 read( ) 호출은 저수준 입력을 수행, scanf( )와 같은 포매팅 기능은 전혀 없음 read( ) 사용 이점 : C 라이브러리 함수에 의해 제공 되는 추가적인 버퍼를 피함 → 매우 빠름 사용 예제 System call: int read ( int fd, char* buf, int count ) charsRead = read (fd, buffer, BUFFER_SIZE); if (charsRead = = 0 ) break; / * 파일 끝 */ if (charsRead = = -1) fatalError ( ); / * 에러 */ 시스템 프로그래밍

14 정규 파일 관리 파일 쓰기 : write( ) 정규 파일이 쓰기를 수행 성공하면 쓰여진 바이트 수 반환, 실패하면 -1 반환 동작 write( ) : 버퍼 buf 에 있는 count 개수의 문자를 파일 기술자 fd에 의해 참조된 파일에 복사, 문자들은 현재 파일 위치에 쓰여지고 그에 따라 파일 위치가 변경됨 O_APPEND 플래그가 fd 에 대해 설정되면 파일 위치는 쓰기 동작 이전에 파일의 끝에 위치하게 됨 write( ) 시스템 호출은 저수준 출력을 수행, printf( )와 같은 포매팅 기능은 전혀 없음 write( ) 사용 이점 : C 라이브러리 함수에 의해 제공되는 추가적인 버퍼를 피함 → 매우 빠름 사용 예제 System call: int write ( int fd, char* buf, int count ) /* 표준 입력 읽기면 임시 파일로 복사 */ if (standardInput) { charsWritten = = write (tmpfd, buffer, charsRead ); if (charsWritten ! = charsRead) fatalError ( ); /* 에러 */ } 시스템 프로그래밍

15 정규 파일 관리 System call: long lseek ( int fd, long offset, int mode )
현재 파일 위치를 이동시킴 현재 파일의 위치를 반환, 그렇지 않으면 -1 반환 동작 offset : long유형의 정수 mode : offset이 어떻게 해석되어야 하는지를 설명 mode에 대한 3가지 값 : ‘/usr/include/sys/file.h’에 정의 L_SET : offset은 파일의 시작 위치에 대한 상대적 위치 L_CUR : offset은 현재 파일 위치에 대한 상대적 위치 L_END : offset은 파일의 끝 위치에 대한 상대적 위치 사용 예제 이동하지 않고 현재 위치를 알려면 현재 위치에 상대적 0인 옵셋 값을 사용 currestOffset = lseek (fd, 0, L_CUR); System call: long lseek ( int fd, long offset, int mode ) lseek (fd, lineStart[i], L_SET); /* 줄을 찾아 읽기 */ charsRead = read (fd, buffer, lineStart [i+1] - lineStart [i] ); /* 읽어야 하는 문자수 = 다음줄의 시작 옵셋 - 현재 줄의 시작 옵셋 */ 시스템 프로그래밍

16 정규 파일 관리 System call: int close ( int fd )
fd가 열린 파일과 관련된 가장 마지막fd이면 관련된 커널 자원 할당을 해제 자동적으로 닫히지만 명시적으로 닫도록 한다 성공하면 0을 반환, 그렇지 않으면 -1반환 동작 파일 제거 : unlink( ) fileName과 파일과의 하드 링크를 제거 fileName이 마지막 링크이면 파일의 자원 할당을 해제 System call: int close ( int fd ) System call: int unlink ( char* fileName ) 시스템 프로그래밍

17 정규 파일 관리 개선된 시스템 호출 기능 inode 구조
Solaris 10: struct vnode /* in /usr/include/sys/vnode.h 180 line */ Fedora 13: struct inode /* in /usr/src/kernels/ fc13-i686.PAE/include/linux/fs.h */ 이 름 기 능 stat 파일에 대한 상태 정보를 얻음 tstat stat와 동일하게 동작 opendir, readdir 디렉토리 내용을 얻음 시스템 프로그래밍

18 (참고) 정규 파일 관리 Utility: monitor [ -t delay ] [ -c count ] { fileName }+
사용자가 명명된 파일을 감시하고, 파일이 수정될 때 마다 정보를 얻도록 하는 프로그램 동작 명세된 파일들을 매 delay 초마다 조사 -t : 기본적인 조사와 조사 사이의 시간(10초)을 변경 수정된 파일에 대한 정보를 화면에 표시 fileName이 디렉토리이면 파일안의 모든 파일 조사 -c : 총 조사 횟수 명시(디폴트로 영원히 조사하게 되어있음) 파일 수정 방법 표시 ADDED : 마지막 조사 이후에 파일이 생성되었음을 나타냄 CHANGED : 마지막 조사 이후에 파일이 수정되었음을 나타냄 DELETED : 마지막 조사 이후에 파일이 삭제되었음을 나타냄 Utility: monitor [ -t delay ] [ -c count ] { fileName }+ 시스템 프로그래밍

19 (참고) 정규 파일 관리 monitor에서의 시스템 호출 monitor는 계속해서 파일과 디렉토리 수정 여부 조사
stat( ) 시스템 호출을 사용하여 명명된 파일의 유형과 마지막 수정 시간에 대한 정보를 얻음 opendir( ), readdir()을 이용해서 디렉토리를 조사 stats라는 상태표를 유지 stats는 자신이 발견한 각 파일에 대해 다음 정보를 저장 파일의 이름 stat( ) 에 의해 얻은 상태 정보 파일이 현재 조사와 이전의 조사 사이에 존재했는지의 기록 조사하는 동안 각 파일을 다음과 같이 처리 파일이 조사표(scan table)에 없다면 추가되었다는 의미에서 ADDED라는 메시지를 표시 파일이 이미 조사표에 있고 마지막 조사 이후에 수정되었다면 CHANGED라는 메시지를 표시 조사의 마지막에 이전의 조사에서는 존재했었으나 현재 조사에서는 존재하지 않는 모든 엔트리들을 표에서 삭제되고 DELETE라는 메시지를 표시 시스템 프로그래밍

20 (참고) 정규 파일 관리 System call: int stat ( char* name, struct stat* buf )
Solaris 10: “/usr/include/sys/stat.h”에 정의되어 있음 (cf. struct vnode /* in vnode.h 180 line) Fedora 13: “/usr/include/bits/stat.h”에 정의되어 있음 (cf. struct inode /* in fs.h 725 line */) 성공하면 0을 반환, 그렇지 않으면 -1 반환 동작 stat( )는 버퍼 buf를 파일 name에 대한 정보로 채움 fstat( )는 stat( )와 똑같이 동작, 첫번째 매개 변수로서 파일 기술자를 취함 /usr/include/sys/dirent.h typedef struct dirent { ino_t d_ino; /* "inode number" of entry */ off_t d_off; /* offset of disk directory entry */ unsigned short d_reclen; /* length of this record */ char d_name[1]; /* name of file */ } dirent_t; System call: int stat ( char* name, struct stat* buf ) int fstat ( int fd, struct stat* buf ) 시스템 프로그래밍

21 (참고) 정규 파일 관리 stat 구조에 포함된 항목 이 름 의 미 st_dev 장치 번호 st_ino inode 번호
이 름 의 미 st_dev 장치 번호 st_ino inode 번호 st_mode 허가권 플래그 st_nlink 하드 링크 개수 st_uid 사용자 id st_gid 그룹 id st_size 파일 크기 st_atime 마지막 접근 시간 st_mtime 마지막 수정 시간 st_ctime 마지막 상태 변경 시간 시스템 프로그래밍

22 (참고) 정규 파일 관리 매크로(macros) 매크로 참을 반환하는 파일 유형 S_ISDIR 디렉토리 S_ISCHR
st_mode를 인수로 취하고 다음 파일 유형에 대해서 참값 1을 반환 “/usr/include/sys/stat.h”에 미리 정의됨 매크로 참을 반환하는 파일 유형 S_ISDIR 디렉토리 S_ISCHR 문자 특수 장치 S_ISBLK 블록 특수 장치 S_ISREG 정규 파일 S_ISFIFO 파이프 시스템 프로그래밍

23 (참고) 정규 파일 관리 System call: int readdir(DIR *df)
디렉토리 파일을 opendir()로 읽기 전용으로 연 다음, 디렉토리에 있는 모든 엔트리를 얻음 구조체 direct는 “/usr/include/sys/dirent.h”에 정의됨 성공하면 디렉토리 엔트리 길이를 반환, 마지막 엔트리가 이미 읽혀지면 0, 에러인 경우엔 -1 반환 동작 파일의 현재 위치로부터 기술자 df를 갖는 디렉토리 파일을 읽고 buf가 포인트하는 구조체를 다음 엔트리로 채움 System call: int readdir(DIR *df) 시스템 프로그래밍

24 (참고) 정규 파일 관리 포함하는 항목들 이 름 의 미 d_off 다음 디렉토리 엔트리의 옵셋 d_fileno inode번호
이 름 의 미 d_off 다음 디렉토리 엔트리의 옵셋 d_fileno inode번호 d_reclen 디렉토리 엔트리의 구조의 길이 d_namlen 파일 이름의 길이 d_name 파일 이름 시스템 프로그래밍

25 (참고) 정규 파일 관리 그 밖의 여러 가지 파일 관리 시스템 호출 이 름 기 능 chown 파일의 소유자 또는 그룹을 바꿈
이 름 기 능 chown 파일의 소유자 또는 그룹을 바꿈 chmod 파일의 허가권 설정을 바꿈 dup 파일 기술자를 복제 dup2 dup와 유사 fchown chown과 동일하게 동작 fchmod chmod와 동일하게 동작 fctnl 여러 파일 특징들에 접근 ftruncate truncate와 동일하게 동작 ioctl 장치를 제어한다. link 하드 링크를 생성한다. mknode 특수 파일을 생성한다. sync 모든 파일 버퍼를 디스크로 옮기도록 스케줄한다. truncate 파일의 길이를 설정한다. 시스템 프로그래밍

26 (참고) 정규 파일 관리 파일 소유주 or 그룹 변경: chown ( ) / fchown( ) 파일의 소유자와 그룹 혹은 둘 중 하나를 변경 성공하면 0을 반환, 그렇지 않으면 -1 반환 동작 chown( )은 fileName의 소유자와 그룹 id를 각각 ownerId와 groupId로 변경 특정 항목에 있는 -1값은 항목과 연관된 값이 변경되지 않아야 함을 의미 슈퍼 유저만이 파일의 소유권 변경 가능 사용자는 자신이 속한 그룹으로의 그룹 변경만 가능 fileName이 심볼릭 링크라면 그 링크가 참조하고 있는 파일 대신에 그 링크의 소유자와 그룹이 변경됨 fchown( )은 파일 이름대신 열린 파일 기술자를 인수로 취함 (예) mychown.c System call: int chown ( char* fileName, int ownerId, int groupId ) int fchown ( int fd, int ownerId, int groupId ) 시스템 프로그래밍

27 (참고) 정규 파일 관리 System call: int chmod ( char* fileName, int mode )
파일 허가권의 변경 : chmod( ) / fchmod( ) 파일의 허가권 플래그들을 변화시킴 성공하면 0, 그렇지 않으면 -1을 반환 동작 chmod( )는 filename의 모드를 mode로 바꿈 mode는 8진수로 제공됨 파일의 모드를 바꾸기 위해서는 그 파일의 소유권을 갖거나 슈퍼 유저가 되어야만 함 fchmod( )는 파일 이름대신 열린 파일 기술자를 인수로 취함 (예) mychmod.c System call: int chmod ( char* fileName, int mode ) int fchmod ( int fd, int mode ) 시스템 프로그래밍

28 (참고) 정규 파일 관리 System call: int dup ( int oldFd )
파일 기술자의 복제 : dup( ) / dup2( ) 파일 기술자 복제를 허용 성공하면 새로운 파일 기술자의 인덱스를 반환, 그렇지 않으면 -1을 반환 동작 dup( )은 가장 작은 할당되지 않은 파일 기술자 값을 찾아 oldFd와 동일한 파일을 가리키게 함 dup2( )는 newFd가 현재 활용중이라면 이를 닫은 후에 oldFd와 동일한 파일을 가리키게 함 원래의 파일 기술자와 복사된 파일 기술자는 동일한 파일 포인터와 접근 모드를 공유함 (예) mydup.c System call: int dup ( int oldFd ) int dup2 ( int oldFd, int newFd ) 시스템 프로그래밍

29 (참고) 정규 파일 관리 System call: int fcntl ( int fd, int cmd, int arg)
파일 기술자와 관련된 플래그들의 설정을 직접적으로 통제 성공하지 못하면 -1을 반환 동작 fcntl( )은 파일 기술자 fd와 관련된 파일에게 cmd에 의해 부호화된 연산을 수행 arg : cmd에 대한 옵션 인수 (예) myfcntl.c System call: int fcntl ( int fd, int cmd, int arg) 12. 시스템 프로그래밍

30 (참고) 정규 파일 관리 cmd의 일반적인 값 이 름 기 능 F_SETFD
이 름 기 능 F_SETFD close-on-exec 플래그를 arg의 최하위 비트(0 or 1)로 설정 F_GETFD close-on-exec 플래그가 설정되어 있다면 최하위 비트가 1인 번호를, 그렇지 않으면 0을 반환 F_GETFL 현재 기술자 상태 플래그들에 해당하는 번호를 반환 F_SETFL 현재 기술자 상태 플래그를 arg로 설정 F_GETOWN SIGIP/SIGURG 시그널을 받도록 현재 설정되어 있는 프로세스 id나 또는 프로세스 그룹을 반환 반환 값이 양수라면 그 수는 프로세스 id를 의미, 음수라면 그 절대값이 프로세스 그룹을 의미 F_SETOWN SIGIP/SIGURG 시그널을 arg로 받아야 하는 프로세스 id나 또는 프로세스 그룹을 arg로 설정 부호화 방식은 F_GETOWN과 같음 시스템 프로그래밍

31 (참고) 정규 파일 관리 System call: int ioctl ( int fd, int cmd, int arg)
장치 고유의 명령어들에 대한 진입점을 제공 한 프로세스가 장치와 관련된 하드웨어 옵션과 드라이버와 관련된 소프트웨어 옵션들을 세트할 수 있도록 해줌 성공하지 못하면 -1을 반환 동작 파일 기술자와 관련된 파일에게 cmd에 의해 부호화된 연산을 수행 arg: cmd에 대한 옵션 인수 $ man attributes 참조 하드 링크의 생성 : link( ) 하드에게 하드 링크를 생성 성공하면 0을 반환, 그렇지 못하면 -1을 반환 link( )는 새로운 레이블 newPath를 생성하여 그것을 레이블 oldPath와 동일한 파일에 연결함 관련 파일의 하드 링크 계수는 1씩 증가 oldPath와 newPath가 다른 물리적 장치에 존재하면 하드 링크는 생성되지 않고 link( )는 실패 오직 슈퍼 유저만이 디렉토리에 링크할 수 있다. (예) mylink.c System call: int ioctl ( int fd, int cmd, int arg) System call: int link ( char* oldPath, char* newPath ) 시스템 프로그래밍

32 (참고) 정규 파일 관리 특수한 파일의 생성 : mknod( ) 특수 파일의 생성을 허용 성공하면 0을 반환, 그렇지 못하면 -1을 반환 동작 mknod( )는 type이 다음 중 하나인 새로운 정규 파일, 디렉토리 혹은 특수 파일인 fileName을 생성 S_IFDIR 디렉토리 (수퍼유저만) S_IFCHR 문자 지향적 파일 (수퍼유저만) S_IFBLK 블록 지향적 파일 (수퍼유저만) S_IFREG 일반 파일 (수퍼유저만) S_IFIFO 명명된 파이프 System call: int mknod ( char* fileName, int type, int device ) 시스템 프로그래밍

33 (참고) 정규 파일 관리 System call: int sync ( )
파일 시스템 버퍼를 비움 sync( )는 항상 성공 동작 sync( )는 파일 시스템 버퍼의 모든 내용을 디스크에 쓰여지도록 스케쥴 함 파일 길이 설정: truncate( ) / ftruncate( ) 파일의 길이를 설정 성공하면 0을, 그렇지 않으면 -1을 반환 truncate( )는 fileName의 길이를 length 값으로 설정 파일이 length보다 짧다면 length보다 긴 부분은 잘림 파일 length보다 짧다면 나머지 부분은 ASCII 널(NULL) 문자로 채워짐 ftruncate( )는 fileName대신에 열려있는 파일 기술자를 인수로 취함 System call: int sync ( ) System call: int truncate ( char* fileName, long length ) int ftruncate (int fd, long length ) 시스템 프로그래밍

34 프로세스 관리 유닉스 시스템에서의 프로세스의 속성 유닉스 상에서의 프로그램 실행 코드 자료 스택(stack)
고유한 프로세스 id 번호 (PID) 유닉스 상에서의 프로그램 실행 처음에 단독으로 존재하는 프로세스 (init, PID =1)를 복사하여 자식 프로세스 생성 프로세스가 복제될 때 부모와 자식 프로세스들 은 각각 PID만 제외하고 모든 면에서 동일 자식 프로세스는 부모와 차별화 하기 위해 자신의 코드를 다른 실행 가능한 파일 코드로 치환 (getty) 시스템 프로그래밍

35 프로세스 관리 초기 프로세스 계층 구조 부모(init, PID=1) 자식(getty, PID=4) 로그인 처리
시스템 프로그래밍

36 부모 프로세스(PID=34) 셸 실행 자식 프로세스 기다림
프로세스 관리 셸이 유틸리티를 실행하는 방법 부모 프로세스(PID=34) 셸 실행 부모 프로세스(PID=34) 셸 실행 자식 프로세스 기다림 자식 프로세스(PID=35) 셸 실행 자식 프로세스(PID=35) 유틸리티 실행 자식 프로세스(PID=35) 종료 부모 프로세스(PID=34) 셸 실행 깨어남 자식 프로세스를 기다림 :wait() 차별화 : exec() 종료 : exit() 시그널 시스템 프로그래밍

37 프로세스 관리 1 2 (sleep) 3 4 사용자 수행중 인터럽트, 인터럽트로부터 복귀 수행대기 깨어남 문맥교환 허용 수면중
프로세스의 상태 및 전이 1 2 3 4 사용자 수행중 시스템 호출 or 인터럽트 복귀 인터럽트, 인터럽트로부터 복귀 프로세스를 스케쥴 수행대기 깨어남 (wake up) 문맥교환 허용 수면중 (sleep) 커널 수면 시스템 프로그래밍

38 프로세스 관리 프로세스의 6상태  Runing ( O )  Runnable ( R )  Sleeping ( S )
현재 CPU를 사용 중  Runnable ( R ) 언제든지 CPU를 사용할 준비가 되어 있음  Sleeping ( S ) 어떤 사건이 발생하기를 기다리고 있음  Suspended SIGSTOP과 같은 시그널이 의해 frozen됨, SIGCONT에 의해 재개  Idle fork()에 의하여 생성은 되었으나, 아직 실행할 수는 없음  Zombified 종결되었으나 그 결과(종결코드)를 아직 부모에게 반환하지 못함 시스템 프로그래밍

39 작업 제어: PROCESS STATE CODES
Unix O Process is running on a processor. S Sleeping: process is waiting for an event to complete. R Runnable: process is on run queue. Z Zombie state: process terminated and parent not waiting. T Process is stopped, either by a job control signal or because it is being traced. Linux D Uninterruptible sleep (usually IO) R Running or runnable (on run queue) S Interruptible sleep (waiting for an event to complete) T Stopped, either by a job control signal or because it is being traced. W paging (not valid since the 2.6.xx kernel) X dead (should never be seen) Z Defunct ("zombie") process, terminated but not reaped by its parent. For BSD formats and when the stat keyword is used, additional characters may be displayed: < high-priority (not nice to other users) N low-priority (nice to other users) L has pages locked into memory (for real-time and custom IO) s is a session leader l is multi-threaded (using CLONE_THREAD, like NPTL pthreads do) + is in the foreground process group Unix/Linux

40 프로세스 관리 시스템 호출 이 름 기 능 fork 프로세스를 복제 getpid 프로세스의 id 번호를 획득 getppid
이 름 기 능 fork 프로세스를 복제 getpid 프로세스의 id 번호를 획득 getppid 부모 프로세스의 id 번호를 획득 exit 프로세스의 종료 wait 자식 프로세스를 기다림 exec 프로세스의 코드, 자료, 스택을 대치 시스템 프로그래밍

41 프로세스 관리 System call: fork ( ) System call: int getpid ( )
부모 프로세스를 자식 프로세스가 복제 받음 부모와 자식 프로세스는 각각 구별되는 id 번호를 갖게 됨 성공하면 자식의 PID를 부모 프로세스에게 반환, 그렇지 않으면 -1을 반환 동작 (예) orphan.c 프로세스 ID 획득 : getpid( ) / getppid( ) getpid( )는 프로세스의 id 번호를 반환 getppid( )는 부모 프로세스의 id 번호를 반환 System call: fork ( ) System call: int getpid ( ) int getppid ( ) 시스템 프로그래밍

42 프로세스 관리 System call: int exit (int status ) 프로세스의 종료 : exit ( )
프로세스의 모든 파일 기술자를 닫고 할당 받은 코드, 자료와 스택을 반환한 후 프로세스를 종료 자식 프로세스가 종료될 때 자식은 부모에게 SIGCHLD 시그널을 보내고 자신의 종료 코드 status가 받아들여질 때까지 대기 종결된 프로세스가 자신의 반환코드를 부모가 받기를 기다리는 경우 좀비(Zombie Process) 프로세스가 됨 종료하기 전에 부모 프로세스가 먼저 종료된 프로세스는 고아프로세스(Orphan Process)가 됨 exit( )는 결코 반환되지 않음 동작 (예) zombie.c System call: int exit (int status ) 시스템 프로그래밍

43 프로세스 관리 System call: int wait (int* status ) 자식 프로세스 기다리기 : wait( )
부모 프로세스가 자식 중의 하나가 종료 되기를 기다리는 상태 (자식의 종료 코드를 받기 위함) 성공하면 종료된 자식의 PID를 반환하고 부호화 되어 있는 상태 코드를 status에 둠 동작 wait( )는 자식 프로세스의 하나가 종료될 때까지 부모 프로세스를 임시 중지시킴 wait( ) 실행 후 아무 자식이 없으면 -1을 반환 wait( ) 실행 후 하나 이상의 자식이 이미 좀비라면 좀비 중 하나의 상태를 반환 wait(&status) /* int status */ status :자식이 exit으로 종료될 때의 상태정보 정상종료 경우 : 하위 8bits는 0, 상위 8bits 는 exit status(자식 프로세스가 exit 명령으로 전달한 값), signal로 종료된 경우 : 하위 8bits는 signal 번호, 상위 8bits는 0 (하위 8 비트 추출) status &= 0x00FF; (상위 8 비트 추출) status >> 8; status &= 0xFF; System call: int wait (int* status ) 시스템 프로그래밍

44 프로세스 관리 프로세스의 차별화 : exec( ) PID, PPID의 번호는 동일하지만, 프로세스가 실행하는 코드와 자료, 스택만이 다른 것으로 교환됨 실제로는 시스템 호출이 아닌 execve( )시스템 호출을 부르는 라이브러리 함수 동작 execl( )은 execlp와 동일, execv( )는 execvp( )와 동일 execl( )과 execv( )는 실행 가능한 파일의 절대 경로 또는 상대 경로 이름이 제공되어야 함 execlp( )와 execvp( )는 path를 찾기 위해 $PATH 환경변수를 사용 실행 가능한 파일이 발견되지 않으면 -1 반환 그렇지 않으면 코드, 자료, 스택을 실행 파일의 것으로 치환하고 새 코드를 실행 성공적인 exec( )는 아무것도 반환하지 않음 System call: int execl( char* Path, char* arg0, ...char* argn, NULL ) int execv( char* Path, char* argv[ ] ) int execlp(char* Path, char* arg0, ...char* argn, NULL) int execvp(char* Path, char* argv[ ] ) 시스템 프로그래밍

45 fork와 시스템 호출 printf(“One\n”); pid = fork(); printf(Two\n”);
PC A BEFORE fork AFTER printf(“One\n”); pid=fork(); printf(“Two\n”); printf(“One\n”); pid = fork(); printf(“Two\n”); PC PC A B 시스템 프로그래밍

46 fork와 exec호출의 조합 pid = fork(); execl(“/bin/ls” …); wait((int*)0);
PC A BEFORE FORK AFTER FORK wait((int*)0); execl(“/bin/ls” …); PC PC A B AFTER FORK AFTER EXEC wait((int*)0); /* first line of ls */ PC PC A 시스템 프로그래밍 B (now runs ls)

47 fork()로 새 프로세스를 생성하는 C program
#include <stdio.h> void main(int argc, char *argv[]) { int pid; /* fork another process */ pid = fork(); if(pid < 0) { /* error occurred */ fprintf(stderr, "Fork Failed"); exit(-1); } else if (pid == 0) { /* child process) */ execl("/bin/ls", "ls", "-l", NULL); } else { /* parent process */ wait(NULL); printf("Child Complete"); exit(0); }

48 fork() example #include <stdio.h> int value = 5; main () {
int pid; pid = fork (); /* Duplicate. Child and parent continue from here */ if (pid != 0) /* pid is non-zero, so I must be the parent */ wait(NULL); printf ("Parent: value = %d\n", value); } else /* pid is zero, so I must be the child */ value += 15; printf ("Child: value = %d\n", value); printf ("PID %d terminates.\n", getpid () ); /* Both processes execute this */ 운영체제

49 fork() + exec() example
후면처리 (background processing) 실행 $ gcc background.c –o background $ ./background ls -l 코드 $ cat background.c #include <stdio.h> main (argc, argv) int argc; char* argv []; { if (fork () == 0) /* Child */ execvp (argv[1], &argv[1]); /* Execute other program */ fprintf (stderr, "Could not execute %s\n", argv[1]); } 운영체제

50 실습 execv, execlp, execvp를 각각 사용하여 exec.c 와 동일한 작업 수행하는 프로그램 작성
자식 프로세스에게 ls –l 작업을 수행시키고 작업이 끝나면 종료 코드(하위 8비트, 상위 8비트 각각)를 출력하는 프로그램 작성 execv char *av[3]; av[0]=“ls”; av[1]=“-l”; av[2]=(char *)0; execv(“/bin/ls”, av); execlp, execvp 쉘 환경변수 PATH를 따름 execlp(“ls”, “ls”, “-l”, (char *)0); execvp(“ls”, av); 시스템 프로그래밍

51 프로세스 관리 System call: int chdir ( char* pathName ) 디렉토리 변경 : chdir( )
현재 작업 디렉토리를 바꿈 성공하면 0, 그렇지 않으면 -1을 반환 동작 chdir( )는 프로세스의 현재 작업 디렉토리를 pathname의 디렉토리로 설정 System call: int chdir ( char* pathName ) 시스템 프로그래밍

52 프로세스 관리 System call: int nice ( int delta ) 우선 순위 변경 : nice( )
디폴트 우선순위를 변경 성공하면 새로운 nice 값을, 그렇지 않으면 -1을 반환 ( -1도 nice 값으로 적합한 값이기 때문에 문제가 발생할 수 있음) 우선 순위의 값 범위 : -20 ~ +19 우선 순위 값이 작을수록 빠르게 실행됨 동작 nice( )는 프로세스의 현재 우선 순위 값에 delta만큼 더함 delta 값은 슈퍼 유저만이 명시할 수 있음 System call: int nice ( int delta ) 시스템 프로그래밍

53 프로세스 관리 System call: int getuid ( ) int geteuid( ) int getgid ( )
getuid( ), geteuid( ), getgid( ), getegid( ) 사용자가 프로세스의 유효 id를 읽는 것을 허용 항상 성공 동작 getuid( )와 seteuid( )는 각각 호출 프로세스의 실제 및 유효 사용자 id를 반환 getgid( )와 getegid( )는 각각 프로세스 실제 및 유효 호출 그룹 id를 반환 System call: int getuid ( ) int geteuid( ) int getgid ( ) int getegid( ) 시스템 프로그래밍

54 프로세스 관리 System call: int setuid (int id ) int seteuid (int id )
setuid( ), seteuid( ), setruid( ), setgid( ), setegid( ), setrgid( ) 프로세스의 실제 및 유효 id 설정 슈퍼 유저에 의해 실행되거나 id가 호출 프로세스의 실제 또는 유효 사용자이거나 그룹 id일 경우 호출이 성공 성공하면 0, 그렇지 않으면 -1을 반환 동작 seteuid( )와 setegid( )는 호출 프로세스의 유효사용자 혹은 그룹 id를 설정 setruid( )와 setrgid( )는 호출 프로세스의 실제 사용자 혹은 그룹 id를 설정 setuid( )와 setgid( )는 호출 프로세스의 유효 및 실제 사용자 또는 유효 및 실제 그룹 id를 명시된 값으로 설정 System call: int setuid (int id ) int seteuid (int id ) int setgid (int id ) int setegid (int id ) 시스템 프로그래밍

55 (C언어 보충) Command-line Arguments
$ echo hello world Output hello, world argc 와 argv[] argc=3 argv[0]: “echo” argv[1]: “hello” argv[2]: “world” Source code $ cat echo.c #include <stdio.h> main(int argc, char *argv[]) { int i; for (i = 1; i < argc; i++) printf(“%s%s”, argv[i], (i < argc-1) ? “ “ : “”); printf(“\n”); return 0; } argv: echo\0 hello\0 world\0 시스템 프로그래밍

56 프로세스 관리 후면처리 (background processing) (예) background.c
$ cat background.c #include <stdio.h> main (argc, argv) int argc; char* argv []; { if (fork () == 0) /* Child */ execvp (argv[1], &argv[1]); /* Execute other program */ fprintf (stderr, "Could not execute %s\n", argv[1]); } 실행 $ gcc background.c –o background $ ./background ls –l 시스템 프로그래밍

57 프로세스 관리 ls > ls.out 리다이렉션
프로세스가 fork 수행 시 자식 프로세스는 부모 프로세스의 파일 기술자의 복사본을 상속 받고 exec를 수행할 때는 닫히지 않는 모든 파일 기술자 들은 아무 영향도 받지 않은 채로 남아 있음 → 리다이렉션 구현 사용예제 수행과정 부모 셸은 fork를 수행하고 자식 셸이 종료되기를 기다림 자식 셸은 파일 “ls.out”를 열고 필요에 따라 파일을 생성하거나 파일의 길이를 설정 자식 셸은 “ls.out”의 파일 기술자를 표준 출력 파일 기술자인 번호 1로 복제하고 원래 “ls.out”의 파일 기술자를 닫음 → 모든 표준 출력 방향이 “ls.out”로 바뀜 자식 셸은 유틸리티 ls를 exec군의 시스템 호출 중 하나로 수행 → ls의 모든 표준 출력이 “ls.out”로 감 자식 셸이 종료될 때 부모 셸은 원래대로 회복됨 ls > ls.out 시스템 프로그래밍

58 프로세스 관리 리다이렉션 (redirection) 실행 $ gcc redirect.c –o redirect
$ cat redirect.c #include <stdio.h> #include <fcntl.h> main (argc, argv) int argc; char* argv []; { int fd; /* Open file for redirection */ fd = open (argv[1], O_CREAT | O_TRUNC | O_WRONLY, 0600); dup2 (fd, 1); /* Duplicate descriptor to standard output */ close (fd); /* Close original descriptor to save descriptor space */ execvp (argv[2], &argv[2]); /* Invoke program; will inherit stdout */ perror ("main"); /* Should never execute */ } 실행 $ gcc redirect.c –o redirect $ ./redirect xx ls -l 시스템 프로그래밍

59 시그널 시그널 예상되지 않은 인터럽트 발생 시 해당하는 프로세스에게 보내는 신호 예
부동 소수점 에러 정전 알람 클락 링 사용자의 종료 요구(예 Ctrl+C ) 사용자의 일지 중지 요구(예 Ctrl+Z ) 각 사건에 대해 고유한 번호의 시그널이 있음 BSD 유닉스에서는 1~31까지 번호 부여 Solaris 9: /usr/include/sys/iso/signal_iso.h 참조 Linux: /usr/include/bits/signum.h 참조 시그널 처리와 관련하여 각 프로세스가 보관하는 3가지 정보  signal handler array 특정 시그널을 받을 때 무엇을 할 것인가  pending signal bitmap 특정 시그널이 도착했는지의 여부 표시  시그널을 구분할 때 사용하는 process group id fork된 프로세스는 자신의 부모 프로세스의 모든 signal handler array를 상속 시스템 프로그래밍

60 시그널 커널 뿐 아니라 허가권이 있는 임의 프로세스 도 다른 프로세스에게 시그널 전송이 가능 시그널 처리 순서
커널 뿐 아니라 허가권이 있는 임의 프로세스 도 다른 프로세스에게 시그널 전송이 가능 시그널 처리 순서 시그널을 받은 프로세스는 현재의 수행 제어 흐름을 정지 시그널 처리기를 실행 시그널 처리가 끝난 후 원래의 수행 제어 흐름을 회복 하나의 작업 수행 시간이 오래 걸릴 경우 알람 클록 시그널이 프로그램을 종료하도록 조정 미리 정의된 시그널 Solaris 9: 38개의 시그널이 /usr/include/sys/iso/signal_iso.h 에 정의 Linux: 31개의 시그널이 /usr/include/bits/signum.h 에 정의 프로그래머 옵션 특별한 시그널이 사용자 제공의 시그널 처리기 구동 커널 제공의 처리기를 구동하게 함 무시되도록 선택 디폴트 처리기의 수행 동작 프로세스를 종료하고 코어 파일을 발생 코어 이미지 파일을 발생하지 않고 프로세스 종료 시그널을 무시하거나 버림(ignore) 프로세스 일시 중지(suspend) 프로세스 다시 시작 (resume) 시스템 프로그래밍

61 시그널 Library Routine: unsigned int alarm (unsigned int count) 터미널 시그널
전면 프로세스에게 시그널을 전달 : Ctrl+C or Ctrl+z Ctrl+C 현재 전면 작업 중에 있는 모든 프로세스들에 SIGINT전달 SIGINT는 프로세스를 종료 Ctrl+z 터미널 드라이버가 현재 전면 작업 중에 있는 모든 프로세스에게 SIGTSTP 전달 SIGTSTP는 프로세스를 일시 정지 알람 시그널 : alarm( ) “Alarm clock”을 화면에 표시한 후 프로세스를 종료 알람 시그널이 보내질 때까지 남아 있는 초(second)의 수를 반환 동작 alarm은 커널에게 count초 후에 호출 프로세스에게 SIGALRM 시그널을 보내도록 지시 만일 count가 0이라면 대기중인 알람 요청은 취소됨 (예) alarm.c Library Routine: unsigned int alarm (unsigned int count) 시스템 프로그래밍

62 시그널 System call: void (*signal ( int sigCode, void ( *func) ( ) ) )( )
디폴트 동작을 무시하도록 사용 sigCode와 관련된 이전 func값 반환, 실패하면 -1반환 동작 signal( ) : 특별한 시그널에 대한 프로세스의 동작을 명시 sigCode : 다시 프로그램될 시그널의 번호 명시 func 값 SIG_IGN : 명시된 시그널의 무시 또는 버림 SIG_DFL : 커널의 디폴트 처리기가 사용 사용자 정의 함수의 주소 : 시그널이 도착했을 때 실행 되어야 하는 함수 시그널 SIGKILL과 SIGSTOP은 사용자 시그널 처리기로 다시 프로그램되는 것을 허용하지 않음 자식 프로세스는 fork( )에 의해 부모로부터 시그널 설정을 상속 받음 프로세스가 exec( )를 수행할 때 이전에 무시된 시그널들을 여전히 무시되고 설치된 처리기들은 디폴트 처리기로 복귀 시그널은 스택에 저장되지 않음(SIGCHLD를 제외) 여러 시그널이 보내져도 하나만이 실제로 처리됨 (예) handler.c (예) critical.c System call: void (*signal ( int sigCode, void ( *func) ( ) ) )( ) 시스템 프로그래밍

63 시그널 System call: int pause ( ) 프로세스의 정지 : pause( )
호출 프로세스를 정지시키고 호출 프로세스가 시그널을 받을 때 복귀 pause를 호출한 프로세스는 SIGALRM 등의 신호가 도착할 때까지 시스템자원을 낭비하지 않도록 수행이 중지됨 어떤 유효한 정보도 반환하지 않음 동작 종료 코드의 보호와 인터럽트 처리기의 연쇄 시그널에 대해서 코드의 임계(critical) 부분의 보호 처리기의 이전 값을 저장하여 임계 코드가 실행된 후에도 처리기가 복구 될 수 있도록 함 System call: int pause ( ) 시스템 프로그래밍

64 시그널 System call: int kill ( int pid, int sigCode ) 시그널 전송 : kill( )
실제로 모든 프로세스를 종료시키지 못함 sigCode 시그널을 PID = pid인 프로세스에게 전송 호출이 성공 송신 프로세스와 수신 프로세스의 소유자가 동일할 경우 송신 프로세스를 슈퍼 유저가 소유하고 있을 경우 동작 pid = 0 시그널은 송신자 프로세스 그룹에 속해 있는 모든 프로세스에게 전송됨 pid = -1 , 송신자 = 슈퍼 유저 송신자를 포함한 모든 프로세스에게 전송됨 pid = -1 , 송신자 ≠ 슈퍼 유저 송신 프로세스를 제외한 송신자와 동일한 소유자에 의해 소유된 모든 프로세스에게 전달 pid < 0 id가 pid의 절대값인 프로세스 그룹에 속해 있는 모든 프로세스에게 전달 (예) limit.c $ limit 5 sleep 100 (예) pulse.c System call: int kill ( int pid, int sigCode ) 시스템 프로그래밍

65 시그널 System call: int getpgrp ( int pid ) 자식 프로세스의 사멸 프로세스의 일시 정시 및 재개
순서 자식 프로세스는 종료할 때 부모 프로세스에게 SIGCHLD 시그널을 보냄 부모 프로세스는 자식의 종료 코드를 받아들이고 좀비화되는 것을 막도록 wait( )를 실행 시그널을 처리하는 처리기를 설치 부모 프로세스가 SIGCHLD 시그널을 무시할 경우엔 자식 프로세스는 자동적으로 좀비화되지 않음 프로세스의 일시 정시 및 재개 시그널 SIGSTOP과 SIGCONT 현재 프로세스 그룹 id 알아내기 : getpgrp ( ) 동작 PID = pid인 프로세스의 프로세스 그룹 id 반환 pid = 0이면 호출자의 프로세스 그룹 id가 반환 System call: int getpgrp ( int pid ) 시스템 프로그래밍

66 시그널 System call: int setpgrp ( int pid, int pgrpId )
fork를 수행할 때 부모와 동일한 그룹의 구성원이 된 자식 프로세스가 그룹을 새로운 값으로 바꾸기 위함 실패하면 -1을 반환 setpgrp( )가 성공하여 프로세스 그룹 id를 설정하기 위한 조건 호출자와 명시된 프로세스는 동일한 소유자를 가지고 있음 호출자는 슈퍼 유저에 의해 소유됨 동작 PID = pid인 프로세스의 그룹 id를 pgrpId로 설정 PID = 0이면 호출자의 프로세스 그룹 id가 pgrpId로 설정 System call: int setpgrp ( int pid, int pgrpId ) 시스템 프로그래밍

67 과제 7…12월 13일(월) 11:59pm까지 Quiz(C) 정답 소스코드와 실행파일을 숙제방에 제출하세요
명령 줄에서 정수형 인수 n을 취하여 n개의 자식 프로세스를 생성하여 각 프로세스는 “I am process PID(1234)" 등으로 자신의 프로세스 번호를 출력하고 종료하는 프로그램 mynproc.c를 작성하여 숙제방에 제출하세요 과제 제출 방법 Electrical Version 1 csmail.incheon.ac.kr ( )의 /home/2009hw/2009ula 또는 2009ulb에 자기 학번으로 숙제방(디렉토리) 만들고 그 안에 복사 자신의 디렉토리 보호 권장: chmod 1700 directoryname Electrical Version 2 multi.incheon.ac.kr ( 의 /export/home/2009hw/2009ula 또는 2009ulb에 자신의 학번으로 숙제방(디렉토리) 만들고 그 안에 복사

68 기말 시험에 대하여 시험 일시: 2010년 12월 13일(월) 6:30pm
시험 범위: 교재 7장, 8장, 9장, 11장, 12장 (수업자료 7장, 8&9장, 11장, 12장) Hand-written A4 1 page Exam note 지참 가능 Work Sheet 7장~12장 문제 50% 이상 나옴 과제 5~7 나옴 Unix/Linux


Download ppt "12. 시스템 프로그래밍 (System Programming)"

Similar presentations


Ads by Google