program definition은 지시(direction)만 내리고 실제 공간을 확보하지는 않는다.
loader를 통해 위 a.out을 main memory에 탑재
program definition에 따라서 공간까지 실제로 확보하는 것은 program instance; process
Process id: a unique numeric identifier for process
non-fixed numeric identifier
Main memory 구조
text
instruction set
data
global data, static 변수
함수 호출과 관계없이 프로그램 종료 때까지 살아있어야 하기 때문에 stack 공간에 저장되면 안됨
heap
malloc(동적 할당)을 위해 남겨둔 공간
완충지역
너무 많은 함수 호출로 인해 stack frame이 너무 많이 쌓여 위 메모리 공간을 침범하는 것을 막기 위한 공간
stackoverflow 발생
stack
함수 호출에 의해 변수 등이 저장되는 공간
함수마다 stack frame이라는 것이 만들어진다.
함수의 지역변수는 해당 stack frame에 생기는 것이다.
함수가 리턴할 때 해당 데이터가 사라짐
stack frame
os가 main함수를 호출하면 stack 아래에 main function에 대한 stack frame이 생김
이곳에는 해당 함수에서 사용하는 local 변수들이 저장됨
parameter 변수, return address(함수 종료 후 다시 돌아가야 할 주소) 등도 포함
그래서 다른 함수에서 같은 변수 이름을 사용해도 둘은 다른 stack frame안에 존재하기 때문에 서로 달리 사용할 수 있는 것이다.
Process Life Cycle
program definition이 실행되는 것이 아니라 그것을 바탕으로 process life cycle이 실행되는 것이다.
프로그램 실행요구
new : process를 만드는 과정
process control block(PCB) 생성
pid 생성
ready
줄 서는 과정(실행을 기다림)
running
누가 먼저 실행할지를 결정하는 과정
우선순위 scheduling, FIFO
wait
I/O를 기다리는
terminated
new에서 address 할당했던 것들과 같은 것들을 회수하여 흔적을 지우는 과정
이와 같이 program definition은 하드디스크에 계속 머물고 있는 것과 달리 process life cycles는 메모리를 동적으로 실행을 했다가 회수까지 전부 한다.
과거의 os는 multi programming을 지원하지 않았음. 즉, 한 program이 실행 중이면 다른 program을 실행하지 못했음.
multi-programming이란 cpu가 쉬는 타임에 다른 프로그램을 실행시키는 것이다.
pre-emptive(강제로 뺏는) 스케쥴링: 실행중인 program이 우선순위가 떨어진다 판단되면 cpu 점유를 뺏어서 ready로 보내고 ready에서 차례를 기다리던 높은 우선순위를 갖는 program이 그 자리를 차지한다.
non-pre-emptive 스케쥴링
라운드 로빈 스케쥴링: 번갈아 가면서 우선순위 할당, 공정성(fairness)
Error handling
에러가 발생하면
음수값이 보통 반환된다.
error가 발생하면 발생한 이유가 환경 변수 errno에 설정된다.
e.g. When open, returns -1 if an error occurs
open과 관련된 에러는 15개 errno value를 갖는다.
file doesn't exit, permission problem, ...
<errno.h>
어떤 number가 어떤 error인지 정보가 담겨있는 헤더 파일
각 에러에 대한 errno symbols과 constants를 저장
각 constant는 알파벳 E로 시작한다.
E.g. ENOENT, EACCESS,...
#include <string.h>
char *strerror(int errnum);
/* maps errnum(errno value) into an error message string & returns a pointer to the string*/
#include <stdio.h>
void perror(const char *msg); /*outputs the string pointed to by msg*/
/*output format"string pointed by msg:errormessage of errno"*/
strerror와 perror의 사용 예
#include "apue.h"
#includ <errno.h>
int main(int argc, char *argv[])
{
fprintf(stderr, "EACCES: %s\n", strerror(EACCES)); //error number to message string
errno = ENOENT;
perror(argc[0]);
exit(0);
}
실행 예
$ ./a.out
EACCES: Permission denied
./a.out: No such file or directory
User identification
user ID
유저를 식별하는 숫자값
시스템 관리자에 의해 할당된다.
0은 superuser or root 유저
group ID
프로젝트로 다같이 유저를 모으는데 사용된다.
만약 full ASCII user/group name이 사용된다면? (ASCII를 사용하지 않는 이유)
추가적인 디스크 공간이 요구된다.
권한 확인을 위한 문자열 비교의 비용이 높다.
userID와 userName은 의미는 같다.
userID와 groupID의 출력 예제
#include "apue.h"
int main(void)
{
//userId, groupId 를 알려주는 함수
printf("uid = %d, grid = %d\n", getuid(), getgid());
exit(0);
}
실행 예
$ ./a.out
uid = 205, grid = 105
Signals
통보(notofication) 수단
Signal
프로세스에서 어떤 조건이 발생했다고 알리는데 사용된다.(커널에 의해)
e.g. if divide by zero, SIGFPE(floating point exception) is sent to the process
Action of process received the signal(받은 시그널에 대한 대응 방법)
signal을 그냥 무시한다..
지정해 놓은 default action이 발생된다.
내가 만든 action을 실행하도록 설정한다.
Signal의 예제
kill
Time values
calendar time
# of seconds since the Epoch
Epoch is 00:00:00 January 1, 1970.
time_t
process time(CPU time)
CPU time used by a process (measured in clock ticks.)
clock ticks are 50, 60, 100 ticks/seconds.
clock_t
Process time 의 표현
clock time
프로세스가 실행 중인 시간의 양
시스템 위에서 실행중인 다른 프로세스들의 수에 의존한다.
그래서 하나의 프로세스를 가지고서만 clock time을 구하는 것이 의미가 있다.
user CPU time
user instruction(user code)에 따른 CPU time
system CPU time
kernel에 따른 CPU time(kernel code)
2.1 기본 명령어
간단한 명령어 사용
$ date // 날짜를 출력하거나 설정
$ hostname
$ uname //시스템 정보를 출력
$ who //시스템에 로그인되어 있는 사용자들을 로그인 정보와 같이 출력해주는 명령어
$ ls //list
$ clear //터미널의 내용을 모두 지우는 명령어
$ passwd //사용자 계정의 비밀번호를 입력 또는 변경하는 명령어
2.2 파일 및 디렉토리
파일의 종류
일반 파일(ordinary file)
데이터를 갖고 있으면서 disk에 저장된다.
디렉터리/폴더
디렉터리 자체도 하나의 파일로 한 디렉터리는 다른 디렉터리들을 포함함으로써 계층 구조를 이룬다.
부모 디렉터리는 다른 디렉터리들을 서브 디렉터리로 갖는다.
특수 파일(special file)
물리적인 장치에 대한 내부적인 표현
키보드(stdin), 모니터(stdout), 프린터 등도 UNIX에서는 모두 파일처럼 사용
디렉터리 계층 구조
유닉스의 디렉터리는 루트로부터 시작하여 계층 구조를 이룬다.
리눅스 디렉터리(유닉스 디렉터리와 유사한 계층 구조를 갖는다.)
홈 디렉터리/현재 작업 디렉터리
홈 디렉터리(home directory)
각 사용자마다 별도의 홈 디렉터리가 있음
사용자가 로그인하면 홈 디렉터리에서 작업을 시작함
현재 작업 디렉터리(curren working directory, cwd)
현재 작업 중인 디렉터리
로그인 하면 홈 디렉터리에서부터 작업이 시작된다.
디렉터리 관련 명령
pwd(print working directory) (시험)
현재 작업 디렉터리를 출력
$ pwd
cd (change directory)
현재 작업 디렉터리를 이동
$ cd [디렉터리]
mkdir (make directory)
새 디렉터리를 만듦
$ mkdir 디렉터리
ls(list)
디렉터리의 내용을 리스트
$ ls
cs1.txt
$ ls -s -> -s(size) ; 히든 파일 미포함6cs1.txt
총 6
$ ls -a -> -a(all; 히든,special 파일 포함)
. .. cs1.txt
$ ls -l -> -l(long,자세하게)
2088 바이트
-rw-r--r-- 1 chang faculty 2088 4월 16일 13:37 cs1.txt
$ ls -asl2 drwxr-xr-x 2 chang faculty 512 4월 16일 13:37 . 2 drwxr-xr-x 3 chang faculty 512 4월 16일 13:37 .. 6 -rw-r--r-- 1 chang faculty 2088 4월 16일 13:37 cs1.txt
총 10 -> (10개의 block을 사용)
정리
명령어
의미
ls
파일 및 디렉터리 리스트
ls -a
모든 파일과 디렉터리 리스트
ls -asl
모든 파일 자세히 리스트
mkdir
디렉터리 만들기
cd 디렉터리
디렉터리로 이동
cd
홈 디렉터리로 이동
cd ~
홈 디렉터리로 이동
cd ..
부모 디렉터리로 이동
pwd
현재 작업 디렉터리 프린트
경로명
파일이나 디렉터리에 대한 정확한 이름
절대 경로명 (absolute pathname)
루트 디렉터리로부터 시작하여 경로 이름을 정확하게 적는 것
상대 경로명 (relative pathname)
현재 작업 디렉터리부터 시작해서 경로 이름을 적는 것
파일 내용 리스트
파일 내용 출력과 관련된 다음 명령어들
cat(catalog), more, head, tail, wc, 등
$ [명령어] [파일]
$ [명령어] [파일*] : 파일 이름을 줄 수도 있고 안 줄 수도 있다.
$ [more] [파일+] : 파일을 한 개 이상을 줄 수 있다.
$ cat cs1.txt -> cs1.txt의 내용을 모니터에 print
$cat -> 파일을 지정하지 않았기 때문에 키보드 입력을 출력하는 모드이다.
... -> 사용자 입력
^D -> 입력 종료
$ cat > cs1.txt -> redirection: 키보드로 입력한 내용은 txt파일에 출력
...
^D
more 명령어
하나 이상의 파일 이름을 받을 수 있으며(한 페이지에 해당하는)
각 파일의 내용을 페이지 단위로 출력
텍스트 파일의 내용을 한 번에 한 화면씩 보여주기 위한 명령어
head 명령어
파일의 앞부분 (10줄)을 출력한다.
tail 명령어
파일의 뒷부분 (10줄)을 출력한다.
wc(word count)
파일에 저장된 줄, 단어, 문자의 개수를 세서 출력
$ wc cs1.txt
38 318 2088 cs1.txt
cp 명령어(copy)
$ cp [파일1] [파일2]
파일 1의 복사본 파일 2를 현재 디렉터리 내에 만듦
$ cp cs1.txt cs2.txt
$ ls -l cs1.txt cs2.txt
-rw-r--r-- 1 chang faculty 2088 4월 16일 13:37 cs1.txt
-rw-r--r-- 1 chang faculty 2088 4월 16일 13:45 cs2.txt # 더 나중에 수정된 것을 볼 수 있음
cp [파일] [디렉터리]
"파일 1의 복사본을 디렉터리 내에 만들어라."
$ cp cs1.txt /tmp
mv(move)
파일 1의 이름을 파일 2로 변경한다.
$ mv 파일1 파일2
$ mv cs2.txt cs3.txt
$ ls -l
-rw-r--r-- 1 chang faculty 2088 4월 16일 13:37 cs1.txt
-rw-r--r-- 1 chang faculty 2088 4월 16일 13:56 cs3.txt
파일을 디렉터리 내로 이동
$ mv [파일] [디렉터리]
$ mv cs3.txt /tmp
rm(remove) 명령어
명령줄 인수로 받은 파일(들)을 지운다.
$ rm 파일+
$ rm cs1.txt
$ rm -r 디렉터리
디렉터리 내의 모든 파일 및 하위 디렉터리들을 단번에 지운다.
rmdir(remove dircectory) 명령어
명령줄 인수로 받은 디렉터리(들)을 지운다.
$ rmdir 디렉터리+
주의: 디렉터리 내에 아무 것도 없어야 한다.
$ rmdir test
정리
명령어
의미
cat 파일*
파일 디스플레이
more 파일+
한 번에 한 페이지씩 디스플레이
head 파일*
파일의 앞부분 디스플레이
tail 파일*
파일의 뒷부분 디스플레이
wc 파일*
줄/단어/문자 수 세기
cp 파일1 파일2
파일1을 파일2로 복사
mv 파일1 파일2
파일1을 파일2로 이름 변경
rm 파일+
파일 삭제
rmdir 디렉터리+
디렉터리 삭제
grep 키워드 파일
파일에서 키워드 찾기
who
호스트에 로그인한 사용자의 정보를 출력하는 명령어
2.3 파일 속성
파일 속성(file attribute)
파일의 이름, 타입, 크기, 소유자, 사용 권한, 수정 시간
$ ls -sl cs1.txt 6 -rw-r--r-- 1 chang faculty 20884월 16일 13:37 cs1.txt
사용 권한(permission mode)
읽기(r), 쓰기(w), 실행(x) 권한
파일의 사용 권한은 소유자(owner)/그룹(group)/기타(others)로 구분하여 관리한다.
예
소유자 그룹 기타
rw-r--r--
chmod(change mode)
커미션 정보를 변경할 때 사용하는 명령어
파일 혹은 디렉터리의 사용권한을 변경하는 명령어
$ chmod [-R] 사용 권한 파일
-R 옵션은 디렉터리 내의 모든 파일, 하위 디렉터리에 대해서도 적용
3 digit으로 사용
owner, group, others
chown(change owner)/ chgrp(change group)
chown 명령어
파일이나 디렉터리의 소유자를 변경할 때 사용한다.
$ chown 사용자 파일
$ chown [-R] 사용자 디렉터리
chgrp 명령어
파일의 그룹을 변경할 수 있다.
$ chgrp 그룹 파일
$ chgrp [-R] 그룹 디렉터리
파일의 소유자 또한 슈퍼 유저(superuser)만이 사용 가능!
2.4 입출력 재지정 및 파이프
출력 재지정(output redirection)
명령어의 표준 출력 내용을 모니터에 출력하는 대신에 파일에 저장
$ 명령어 > 파일
$ who > names.txt
기존 파일의 내용이 지워짐
출력 재지정 예
$ cat > list1.txt
Hi!
This is the first list.
^D
$ cat > list2.txt
Hello !
This is the second list.
^D
$ cat list1.txt list2.txt >list3.txt
$ cat list3.txt
Hi!
This is the first list.
Hello !
This is the second list.
말 그대로 출력 재지정이다! (화면 -> 파일)
출력 추가(append)
명령어의 표준 출력을 모니터 대신에 기존 파일에 추가
$ 명령어 >> 파일
$ cat >> list1.txt
Bye !
This is the end of the first list.
^D
$ cat list1.txt
Hi !
This is the first list.
Bye !
This is the end of the first list.
입력 재지정(input redirection)
명령어의 표준 입력을 키보드 대신에 파일에서 받는다.(방향이 반대 '<')
$ 명령어 < 파일
$ wc < list1.txt #word count
4 17 71 list1.txt
문서 내 입력(here document)
< : 지정된 파일로부터 입력을 받음
> : 지정된 파일로 출력
>> 출력을 지정된 파일에 추가(append)
<< : 실제 파일은 아니지만, 시스템에 입력되는 파일처럼 보이는 입력 라인
명령어의 표준 입력을 << 다음의 단어가 다시 나타날 때 까지의 내용으로 사용
명령어를 실행할 때 문서(script) 내에서 입력을 줄 때 사용
단어가 나올 때까지의 명령어를 실행 중인 프로그램에 입력해 줄 수 있다.
$ 명령어 << 단어 #(delimeter 단어)
...
단어
$ wc << end
hello !
word count
end
2 420
list1.txt 파일의 워드 카운트 결과를 result 파일에 기록한다.
$ wc < list1.txt > result
파이프
로그인 된 사용자들을 정렬해서 보여주기
$ who > names.txt $ sort < names.txt
$ 명령어1 | 명령어2
명령어1의 표준 출력을 명령어2의 표준입력으로 바로 받는다.
기호 | 는 좌측의 출력을 우측의 입력으로 인가한다.
$ who | sort
첫 번째 방식과의 차이점은 위와 같이 작성하면 names.txt와 같은 임시 파일을 생성하지 않아도 된다는 점이다.
2.5 후면 처리 및 프로세스
전면 처리 vs. 후면처리
전면 처리
명령어를 입력하면 명령어가 전면에서 실행되며 명령어 실행이 끝날 때까지 쉘이 기다려 준다.
명령어는 키보드와 모니터로 입출력
한 명령어만 실행 가능, 실행 중인 명령어는 Ctrl-C 입력 시 강제 종료, Ctrl-Z 입력 시 실행 중단
중단 된 명령어는 prompt에서 fg 명령어 입력 시 실행이 계속 됨
후면 처리
명령어들을 후면에서 처리하고 전면에서는 다른 작업을 할 수 있으면 동시에 여러 작업을 수행할 수 있다.
$ [명령어] &
후면 처리 예
fg(foreground)
현재 디렉토리에서 test.c라는 이름을 가진 파일을 찾아라
$ (sleep 100; echodone) & #두 명령어를 background로 실행 [1] 8320 $ find . -name test.c -print & #test.c 라는 파일을 찾아서 print(bg 실행) [2] 8325 $ jobs# 후면(bg)에서 실행되고 있는 작업들을 리스트 [1] + Running ( sleep 100; echodone ) [2] - Running find . -name test.c –print
$ fg %작업 번호
$ fg %1 #fg실행으로 바뀜 ( sleep 100; echodone )
후면 처리 입출력
$ find . -name test.c -print > find.txt & # 출력 뒤섞임 방지(fg가 표준 출력이기 때문) $ find . -name test.c -print | mail chang & # test.c 내용을 mail의 입력으로 $ wc < inputfile & # 후면처리는 키보드 입력 불가능, 파일로부터 받아야 함
프로세스(process)
실행 중인 프로그램을 프로세스(process)라고 부른다.
각 프로세스는 유일한 프로세스 번호 PID를 갖는다.
ps(process) 명령어를 사용하여 나의 프로세스들을 볼 수 있다.(내가 실행시킨 프로세스)
$ ps u # 자세한 정보 출력
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
chang 8695 0.0 0.0 5252 1728 pts/3 Ss 11:12 0:00 -csh
chang 8793 0.0 0.0 4252 940 pts/3 R+ 11:15 0:00 ps u
ps aux
$ ps aux # 시스템 내의 모든 프로세스 정보 출력
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 2064 652 ? Ss 2011 0:27 init [5]
root 2 0.0 0.0 0 0 ? S< 2011 0:01 [migration/0]
root 3 0.0 0.0 0 0 ? SN 2011 0:00 [ksoftirqd/0]
root 4 0.0 0.0 0 0 ? S< 2011 0:00 [watchdog/0]
...
root 8692 0.0 0.1 9980 2772 ? Ss 11:12 0:00 sshd: chang [pr
chang 8694 0.0 0.0 9980 1564 ? R 11:12 0:00 sshd: chang@pts
chang 8695 0.0 0.0 5252 1728 pts/3 Ss 11:12 0:00 -csh
chang 8976 0.0 0.0 4252 940 pts/3 R+ 11:24 0:00 ps aux