Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
Schedule for your own shell
• 1st
– shell 기본기능
– fork / exec
– Background Processing/ Sequential Execution
– ls, find, grep
• 2nd
– Environment variables/ Shell variables
– built-in command
• cd, exit, set, unset, alias, unalias, umask
Shell
• 쉘의 시작
– Text mode : 시스템에 로그인하면 쉘 상태로 진입
– GUI mode : xterm이나 hanterm등의 터미널 실행으로 쉘 진입
• 쉘의 역할
– 명령을 해석하고 실행
• 쉘의 종류
– bash, csh, ksh, sh, tcsh, zsh…
• 리눅스 배포본 = Kernel + Shell + Application
fork()
• 새로운 프로세스 생성
– 생성된 프로세스 : 자식 프로세스(child process)
– fork()를 호출한 프로세스 : 부모 프로세스(parent process)
• fork()가 이루어지는 시점에서 두 프로세스가 동시에작업 수행
• 함수 정의
fork() Example I#include <stdio.h> #include <string.h> #include <sys/types.h>
#define MAX_COUNT 200 #define BUF_SIZE 100
int main(void){ pid_t pid; int i; char buf[BUF_SIZE]; fork(); pid = getpid(); for (i = 1; i <= MAX_COUNT; i++) {
sprintf(buf, "This line is from pid %d, value = %d\n", pid, i); write(1, buf, strlen(buf));
}return;}
fork() Example II#include <stdio.h>#include <sys/types.h>
#define MAX_COUNT 200void ChildProcess(void); /* child process prototype */void ParentProcess(void); /* parent process prototype */
int main(void){
pid_t pid;
pid = fork();if (pid == 0)
ChildProcess();else
ParentProcess();return;
}
fork() Example II
void ChildProcess(void){
int i;
for (i = 1; i <= MAX_COUNT; i++){printf("This line is from child, value = %d\n", i);sleep(1);
printf(" *** Child process is done ***\n");}
void ParentProcess(void){int i;
for (i = 1; i <= MAX_COUNT; i++){printf("This line is from parent, value = %d\n", i);sleep(1);
}printf("*** Parent is done ***\n");
}
check the process tree using „pstree‟ commandrunning this example
exec() family
• 실행 파일을 수행
• exec 계열의 함수가 사용된 뒤의 코드는 메모리에서 삭제
– exec 함수에 인자로 들어간 실행파일의 코드가 메모리에 올라감
• fork()를 항상 수반
– exec수행 후 다른 코드는 의미가 없어짐
– fork()를 이용해 child process가 exec를 수행
– exec 뒤의 코드는 parent process가 수행
exec() family
• exec family
– execl : 실행 파일 수행
– execle : 실행파일에 환경변수를 인자로 넘겨줌
– execlp : 현재 디렉토리의 실행 파일 수행
– execv : 인자를 배열에 저장해서 실행 파일 수행
– execve : 환경변수를 인자로 넘겨줌. 인자는 배열에 저장
– execvp : 현재 디렉토리의 실행파일수행, 인자는배열에 저장
• section 8.10 exec functions
– 실제 exec 함수군의 prototype 정의(다른 PPT에나와있음)
exec() family
Int execl(const char *pathname, const char *arg0, …/* (char *)0 */);
• 실행파일 수행
Int execle(const char *pathname, const char *arg0, …/* (char *)0, char *const envp[] */);
• 실행파일에 환경변수를 인자로 넘겨줌
Int execlp(const char *pathname, const char *arg0, , …/* (char *)0 */);
• 현재 디렉토리의 실행 파일 수행
Int execv(const char *pathname, *const argv[]);
• 인자를 배열에 저장해서 실행 파일 수행
execve(const char *pathname, *const argv[], …/* (char *)0, char *const envp[] */);
• 환경변수를 인자로 넘겨줌. 인자는 배열에 저장
execvp(const char *pathname, *const argc[]);
• 현재 디렉토리의 실행파일수행, 인자는 배열에 저장
exec() Example I
#include <unistd.h>
Int main(void){
puts(“exec before\n”);
execl(“/bin/ls”, “ls”, “-l”, NULL);
puts(“exec after..blahblah”);
return;
}
exec() Example II
#include <unistd.h>
Int main(void){
if(fork()==0){
execl(“/bin/ls”, “ls”, “-l”, NULL);
}
else{
wait(NULL);
puts(“Child Finished\n”);
}
}
Background Processing
• background / foreground
• 명령끝에 & 문자를 넣어 실행
– e.g) gcc shell.c &
– 작업번호와 프로세스 ID를 출력하고 background로 돌아가고, 쉘 프롬프트 출력.
– 작업번호는 background 명령에 순서대로 부여.
– 사용자 입력이 필요한 명령은 background로 보낼 수 없음
– jobs 명령을 이용하여 background process를 확인할 수있음.
– fg/bg명령을 사용하여 background/foreground 상태에서실행가능.
– kill 명령으로 background 작업 멈춤
- 20 -
setpgid()
#include <unistd.h>
int setpgid(pid_t pid, pid_t pgid);– 프로세스는 setpgid 함수를 이용하여 프로세스의 그룹을 바꿀 수 있
음.
– pid 번호를 가진 프로세스의 그룹 ID를 pgid 그룹으로 변경
– pid가 0이면 호출하는 프로세스 ID를 사용
– pgid가 0이면 pid에 해당하는 프로세스가 그룹 리더
– 리턴 값 : 0 – success
1 – fail
• New• A process that has just been created but has not
yet been admitted to the pool of executable processes by the operating system. Typically, a new process has not yet been loaded into main memory, although its process control block has been created
Five-State Process Model
RunningReady ExitNew
Blocked
Admit
TimeOut
Dispatch
Release
EventOccurs Event
Wait
• Ready• A process that is prepared to execute when given
the opportunity
Five-State Process Model
RunningReady ExitNew
Blocked
Admit
TimeOut
Dispatch
Release
EventOccurs Event
Wait
• Running• The Process that is currently being executed. For
this chapter, we will assume a computer with a single processor, so at most one process at a time can be in this state
Five-State Process Model
RunningReady ExitNew
Blocked
Admit
TimeOut
Dispatch
Release
EventOccurs Event
Wait
• Blocked• A process that is cannot execute until some event
occurs, such as the completion of an I/O operation
Five-State Process Model
RunningReady ExitNew
Blocked
Admit
TimeOut
Dispatch
Release
EventOccurs Event
Wait
• Exit• A process that has been released from the pool
of executable processes by the O/S, eithe because it halted or because it aborted for some reason
Five-State Process Model
RunningReady ExitNew
Blocked
Admit
TimeOut
Dispatch
Release
EventOccurs Event
Wait
• Interrupt• A mechanism that peripheral devices inform an asynchronous
event to Linux
• Due to some sort of event that is external to and independent of the currently running process
• Ex) Completion of I/O operation
Interrupt
• Exception• Inform an synchronous software event to Linux
• Divided by zero
• Invalid machine code
• Overflow
• Page fault
• Segmentation fault
• Protection fault
Exception
• Trap• Relates to an error or exception condition generated within the
currently running process
• Ex) illegal file access attempt
• IDT ( Interrupt Description Table )
Trap
• divide_error()• debug()• nmi()• ….• segment_not_present()• ….• page_fault ()• ….
Common trap
handler for 80*86
• Timer_interrupt• Hd_interrupt• ….
Device interrupt
handler
• System_call()System_call vector
0x0
0x20
0x80
Signal handling
• 시그널(signal)의 개념
– 시그널
• 소프트웨어 인터럽트(interrupt)
• 프로세스들 사이에서 비동기적 사건의 발생을 젂달
– 시그널 이름
• 서로 다른 사건을 구별하기 위하여 여려 종류의 시그널을 제공
• 모든 시그널은 „SIG‟로 시작하는 이름을 갖는다
– 시그널에 대한 작업
• 시그널의 발생, 젂달, 처리
signal handling
• 시그널의 발생(generation)
– 터미널에서 특수키를 누르는 경우
– 하드웨어의 오류
• 0으로 나눆 경우, 잘못된 메모리를 참조하는 경우 등
– kill함수의 호출
• 특정 프로세스나 프로세스 그룹에서 원하는 시그널을발생/젂달한다
• 대상프로세스에 대한 권한이 있어야 한다.
– kill명령의 실행
• 내부적으로 kill함수를 호출한다
– 소프트웨어적 조건
• 네트워크에서의 데이터 오류(SIGURG), 파이프 작업에서의 오류(SIGPIPE), 알람의 종료(SIGALRM)등
signal handling
• 시그널의 젂달(delivery)
– 발생된 시그널이 수싞되어 정해진 방법대로 처리되는 것
– 지연(pending) : 발생된 시그널이 젂달되지 못한상태
• 시그널의 블록(block)
– 블록이 해제되거나 무시하도록 변경될 때까지 지연된 상태로 남는다.
– 시그널 마스크(signal mask) : 블록될 시그널 집합
signal handling
– 시그널의 처리(disposition, action)
• 시그널을 무시한다(ignore)– SIGKILL과 SIGSTOP 시그널을 제외한 모든 시그널을 무시할 수
있다.
– 하드웨어 오류에 의해 발생한 시그널에 대해서는 주의해야 한다.
• 시그널을 처리한다(catch)– 시그널이 발생하면 미리 등록된 함수(handler)가 수행된다
– SIGKILL과 SIGSTOP 시그널에는 처리할 함수를 등록할 수 없다.
• 기본처리 방법에 따른다. (default)– 특별한 처리방법을 선택하지 않은 경우
– 대부분 시그널의 기본 처리방법은 프로세스를 종료시키는 것이다.
signal handling
• 시그널 처리 방법의 선택
– typedef void(*sighandler_t)(int signo);
– sighandler_t signal(int signum, sighandler_thandler);
– 지정한 시그널에 대한 세 가지 처리 방법 중 하나를 선택한다.
– signo 인자 : 시그널 번호
signal handling
– handler 인자
• SIG_IGN : 지정한 시그널을 무시한다.
• SIG_DFL : 기본 처리 방법에 따라 처리한다.
• 사용자 정의 함수(signal handler) : 시그널이 발생하면호출될 함수의 주소
– 리턴값 : 지정한 시그널에 대한 이젂까지의 처리방법
Signal handling
• When you press….
– Ctrl + z
• SIGSTOP is sent to the process.
• 프로세스는 blocked 상태에 머물게 됨.
– Ctrl + c
• SIGINT is sent to the process.
• 프로세스는 Terminate
Signal handling Example#include “errhdr.h”
static void sig_usr(int);
int main(void){
if(signal(SIGUSR1,sig_usr)==SIG_ERR)err_sys(“can‟t catch SIGUSR1”);
if(signal(SIGUSR2,sig_usr)==SIG_ERR)err_sys(“can‟t catch SIGUSR2”);
for(;;)pause();
}static void sig_usr(int signo){
if(signo==SIGUSR1)printf(“received SIGUSR1\n”);
else if(signo==SIGUSR2)printf(“received SIGUSR2\n”);
elseerr_dump(“received signal %d\n”,signo);
}
Assignment #3
• Requirements
– shell 실행으로 쉘 시작
• 커맨드 프롬프트는 “사용자이름@현재위치 $”
• ex)root@splab $
• 제작한 ls, find, grep 수행 가능
• Shell에서 exec으로 수행하도록
• 하나의 프로젝트로 묶어서 사용하도록
– background 수행 가능
– 순차실행가능
– Ctrl+C(SIGINT) 시그널 처리
• 프로그램 종료되지 않음
• 커맨드실행주에는 SIGINT 가능하게 처리
Makefile Tips
• 프로젝트 디렉토리 구조
• Makefile에서 다른 디렉토리의 Makefile호출
– kwsh/makefile의 경우 “make –C kwls”를 사용하면 해당 디렉토리의 makefile을 호출