단일 처리기인 경우에는 Critical Section인 경우에 interrupt를 disable 시키면 되지만, 다중 처리기 환경에서는 비효율적이다. 왜냐하면 interrupt를 보내지 말라는 메세지를 모든 처리기에 전달해야 되고 Critical Section에 들어가기전에 메세지를 일일이 다 확인해야 하기 때문이다.

따라서 많은 하드웨어들이 동기화 문제를 해결하기 위한 Synchronization hardware를 가지고있는데 이중, testandset과 swap을 살펴보자.

 

testandset();

 

boolean TestAndSet(boolean *target){ 

boolean rv = *target;

*target = TRUE;

return rv;

}

testandset함수는 들어온 값을 TRUE로 바꿔주고 원래있던 값을 반환하는 함수이다.

 

do{

while(TestAndSet(&lock));    //lock을검사하고 TRUE면, 루프를 FALSE면 CriticalSection진입.

 

// Critical Section

 

lock = FALSE;                    //CriticalSection을통과하고다른프로세스의 진입을 허용한다는 의미로 lock을 FALSE로 바꿔준다.

 

//remainder section

}while(TRUE);

 

lock은 맨처음 FALSE로 초기화가 되어 있다. 맨처음에 들어온 프로세스가 testandset을 거치고 나면 lock은 TRUE로 바뀌고 맨처음에 들어온 프로세스는 Critical section에 들어오게 된다. Context-switch가 일어나도 lock은 FALSE이기 때문에 다른 프로세스들은 while루프를 돌게됨.

하지만 임의의순서대로 Critical Section에 들어가기 때문에 어느 한 프로세스는 계속 기다리는 경우의 수가 발생할 수도 있다. 따라서 Bounded waiting을 만족하지못한다.

 

swap();

 

void Swap(boolean *a,boolean *b){

boolean temp = *a;

*a = *b;

*b=temp;

}

 

 

do{

key = TRUE;

while(key == TRUE)            //맨처음 프로세스가 통과할때 lock은 FALSE이므로while루프를

swap(&lock,&key);            //한번실행하고 나가지만 다른프로세스가 들어오면 lock,key 모두 TRUE이므로 계속해서 while을 돌게 된다.

 

//Critical Section

 

lock = FALSE;                //Critical section을 사용하고 난 후에는 lock = FALSE;로 바꿔주어서 다른 프로세스의 진입을 허용함.

 

//remainder section

}while(TRUE);

 

하지만 swap();도 Bounded waiting을 만족하지 못함.

 

 

최종적인 코드 (Bounded waiting 만족)

 

do{

waiting[i]=TURE;

key = TRUE;

while(waiting[i] && key)        //맨처음프로세스만 lock=FALSE이므로 통과하고 나머지는

key=TestAndSet(&lock);  //계속 루프를 돌게 된다.

waiting[i]=FALSE;                //크리티컬섹션의 진입허용권을 얻게되었으므로 표시를해줌.

  //Process와Bounded waiting 을 만족하게끔.

//Critical section

 

j=(i + 1) % n;                    //최대갯수 n개로 나눠준다. 원형 Queue를 생각하면 편할듯.

while((j != i) && !waiting[j])

j=(j+1)%n;

 

if(j==i)                            //if 문 조건에 해당하면 나말고 다른 프로세스가 없다는 뜻.

lock =FALSE;

else                            //다른 프로세스의 진입허용.

waiting[j] = FALSE;

 

//remainder section

 

}while(TRUE);

'O.S' 카테고리의 다른 글

Mutex  (0) 2012.05.16
Classic Problems of Synchronization / Monitor  (0) 2012.04.27
Semaphore  (0) 2012.04.27
파일 디스크립터(File descriptor)  (0) 2012.04.24
공유메모리 함수 - shmget , shmat , shmdt  (2) 2012.04.23

Semaphore

 

 

int형 변수로 사용자마음대로 수정할 수 없고 wait,signal을 이용해서만 수정이 가능하다.

공유데이터 문제(Critical Section)을 해결하기 위한 문제중 하나로써, Critical Section 코드 위에 세마포어로 락을 걸어주어 프로세스가 크리티컬 섹션을 진행하다가 Context-Swich가 일어나도 다른 프로세스의 접근을 막아주어 하나의 프로세스만 들어가게 끔 만들어 준다.

 

 

Wait(S){                 // S는 세마포어를 지칭함.

while(S<=0);    // 세마포어 변수가 0이하 일때에는 루프를 돌게해서 락을 건다.

s--;                // 세마포어 변수가 1이라서 락인부분을 통과하면 Critical Section을 사용하고 다른 프로세스의 접근을 막기위해서 세마포어를 -1 시켜준다.

}

 

Signal(S){

S++;                //Critical Section을 거치고 난 프로세스가 실행하는 함수로 다른 프로세스의 접근을 허용함.

}

 

또한, 하나의 프로세스가 wait,singal을 사용하여 세마포어 값을 변경하고 있을 때에는 다른 프로세스가 값을 변경할 수 없다. Wait , Signal을 실행시에는 Atomic 해야 한다.

Atomic => 실행중에 interrupt가 발생하지 않도록 해주는 것.

 

운영체제는 세마포어를 Binary semaphore와 Counting semaphore로 나누기도 한다.

바이너리 세마포어는 0 or 1만을 값으로 가지지만 카운팅 세마포어의 값은 제한이 없다. 바이너리 세마포어(이진 세마포어)는 위에서 설명한 방식대로 공유리소스에 하나의 프로세스만 넣는 기법이고, 카운팅 세마포어는 공유리소스의 접근할 수 있는 최대 허용치만큼을 초기값으로 가지고 나서 공유 자원에 프로세스가 들어갈때 마다 값을 -1 해주고 세마포어 변수가 0이 되면 다른 프로세스의 접근을 막는 방식이다.

 

세마포어의 방법에는 2가지가 있는데...

Busy waiting

Critical Section을 사용중인 프로세스가 signal에 들어가기 전까지 다른 프로세스들은 while루프를 돌고 있으므로 오버헤드가 단점이다.

 

Blocking & Wake-up

waiting Queue를 만들어 waiting process를 저장하고 뮤텍스를 두어서 Critical Section을 사용한 프로세스가 waiting queue에 있는 process중 하나에게 뮤텍스를 전달하면 전달받은 프로세스가 Critical Section에 들어가는 방식. 하지만 크리티컬섹션 실행시간이 아주 짧을때는 큐에 집어넣고 뮤텍스를 전달하고 다시 큐를 빠져 나오게 해야 하므로 오버헤드가 busy waiting보다 더 클 수가 있다.

 

Semaphore problem

 

Deadlock 현상

프로세스들이 Critical Section에 들어가지 못하고 계속 while루프만 도는 것을 의미함. 예를 들어

 

P1                             P2

wait(S);                   wait(Q);

wait(Q);                   wait(S);

 

     C r i t i c a l   S e c t i o n

 

Signal(S);                Signal(Q);

Signal(Q);                Signal(S);

 

와 같은 코드가 있다면, 맨처음 p1의 wait(S);가 일어나고 Context-Switch가 일어 난 후에 P2의 wait(Q);가 실행되고 다시 P1이 실행된다면 P2의 wait(Q);에 의해서 P1 프로세스는 wait(Q);에서 signal(Q);가 있을때까지 루프를 돌게 된다. 루프를 돌던 중 P2가 실행되고 P2도 wait(S);에서 계속 루프를 돌게 된다. P1,P2둘다 아무런 진척이 없이 무한루프에 빠지는 현상을 Deadlock현상이라고 한다.

 

Starvation 현상

앞의 스케쥴링 기법에서도 있었던 문제점인데, 세마포어를 사용할때 Block & wake-up 방식을 이용한다고 가정하자. 이때 Queue는 LIFO방식으로 작동한다면, 처음에 들어온 프로세스는 Starvation현상이 발생할 것이다.

 

Priority Inversion(우선순위 역전현상)

우선순위가 낮은 프로세스가 Critical Section을 실행하던 중 우선순위가 높은 프로세스가 들어오면 CPU는 우선순위가 높은 프로세스를 실행한다. 그러다가 실행중 프로세스보다 더 높은 우선순위의 프로세스가 들어왔는데 Critical Section에 진입해야 하는 경우에 wait를 이미 한번 호출했기 때문에 진입을 할 수가 없다. 이처럼 우선순위가 낮은 프로세스가 문제가 되어 우선순위가 높은 프로세스가 진행할 수 없는 경우를 뜻한다.

 

이럴경우 우선순위 계승방법으로 해결이 가능한데, 우선순위가 낮은 T3가 signal을 호출하기 전까지만 T1의 우선순위를 계승하는 방법이다. signal을 호출하고 나면 우선순위가 원래대로 돌아오게 됨.

 

 

 

 

TCP 서버의 함수호출 순서.

소켓프로그래밍 짜다가 너무 헷갈려서 한번올려본다. 원래는 이런거 올릴생각없었는데 ㅠㅠ

 

함수하나하나 살펴보자.

 

#include<sys/socket.h>에 정의되어 있다.

 

int socket(int domain, int type, int protocol);    //성공시 파일 디스크립터,실패시 -1반환.

 

domain -> 소켓이 사용할 프로토콜 체계(Protocol Family)정보 전달.

type -> 소켓의 데이터 전송방식에 대한 정보 전달.

protocol -> 두 컴퓨터간 통신에 사용되는 프로토콜 정보 전달.

 

int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen);    //성공시 0,실패시 -1반환.

 

sockfd -> 주소정보를 할당할 소켓의 파일 디스크립터.

myaddr -> 할당하고자 하는 주소정보를 지니는 구조체 변수의 주소 값.

addrlen -> 두 번째 인자로 전달된 구조체 변수의 길이정보.

 

int accept(int sock, struct sockaddr * addr, socklen_t * addrlen);    //성공시 생성된 소켓의 파일 디스크립터, 실패시 -1 반환.

 

sock -> 서버 소켓의 파일 디스크립터 전달.

addr -> 연결요청 한 클라이언트의 주소정보를 담을 변수의 주소 값 전달, 함수호출이 완료되면 인자로 전달된 주소의 변수에는 클라이언트의 주소정보가 채워진다.

addrlen -> 두번째 매개변수 addr에 전달된 주소의 변수 크기를 바이트 단위로 전달, 단 크기정보를 변수에 저장한 다음에 변수의 주소 값을 전달한다. 그리고 함수호출이 완료되면 크기정보로 채워져 있던 변수에는 클라이언트의 주소정보 길이가 바이트 단위로 계산되어 채워진다.

 

int listen(int sockfd, int backlog);    //성공시 0, 실패시 -1반환

 

sockfd -> 서버 소켓의 파일 디스크립터 전달.

backlog -> 연결요청대기큐 허용 갯수 설정하는 정수가 들어감.

 

 

 

'Programming > Socket' 카테고리의 다른 글

클라이언트 IP 가져오기  (0) 2012.05.14
멀티프로세스 소스  (0) 2012.05.10
멀티프로세스 서버  (0) 2012.05.08
소켓의 옵션  (0) 2012.05.07
Socket 함수 구조체  (0) 2012.04.24

TCP / IP 프로토콜 스택

 

위 그림을 통해 TCP/IP스택이 총 네 개의 계층으로 나뉨을 알 수 있고, 이유는 데이터 송수신의 과정을 네 개의 영역으로 계층화했다는 의미이다. 인터넷 기반의 효율적인 데이터 전송이라는 문제를 작게 나눠서 계층화함으로써 탄생한 것이 TCP/IP이다.

 

LINK계층

 

LINK계층은 물리적인 영역의 표준화에 결과이다. 이는 가장 기본이 되는 영역으로 LAN,WAN,MAN과 같은 네트워크 표준과 관련된 프로토콜을 정의하는 영역이다. 두 호스트가 인터넷을 통해 데이터를 주고받기 위해 물리적인 연결이 존재해야 하는데 이부분에 대한 표준을 LINK계층에서 담당함.(2 - 데이터 링크 계층)

 

IP계층

 

LINK계층으로 물리적인 연결이 형성되었으므로, 데이터를 보낼 준비가 된 것이다. 하지만 이때의 문제점이 있는데 바로 데이터 전송을 경로를 설정해야 하는 것이다. 목적지로 데이터를 전송하기 위해서 거치는 경로를 결정하는게 바로 IP계층이고, 이떄 사용하는 프로토콜이 IP이다.

IP자체는 비 연결지향적이며 신뢰할 수 없는 프로토콜임. 데이터를 전송할 때마다 거쳐야 할 경로를 설정해 주지만, 경로는 일정치 않고, 혹시 데이터 전송 도중 경로상 문제가 발생하면 다른 경로를 선택해 주는데, 이과정에서 데이터가 손실되거나 오류가 발생하는 등의 문제가 발생한다고 해서 이를 해결해주지 않는다. 즉 오류발생에 대한 대비가 되어있지 않은 프로토콜이다.(3 - 네트워크계층)

 

TCP/UDP 계층

 

호스트 대 호스트의 데이터 송수신 방식을 약속한 것이 TCP/UDP이며, TCP는 확인절차를 걸쳐서 신뢰성이 없는 IP에 신뢰성을 부여한 프로토콜이다. 데이터 전송을 위한 경로를 IP에서 설정해줬으므로, 데이터를 전송할 일만 남았다. TCP/UDP는 IP계층에서 알려준 정보를 바탕으로 데이터의 실제 송수신을 담당한다.(4 - 전송계층)

IP는 오로지 하나의 패킷전송만을 염두해 두고 만들어졌기 때문에 패킷 A가 먼저 보내졌어도 패킷B가 먼저 도착할 수도 있는 것이다. 하지만 TCP프로토콜이 추가 된다면 데이터를 송수신할때 받았는지 확인절차를 거치기 때문에 신뢰성이 증가함.

 

APPLICATION 계층

 

소켓을 이용해 무엇인가를 만드는 과정에서 프로그램의 성격에 따라 클라이언트와 서버간의 데이터 송수신에 대한 약속들을 APPLICATION프로토콜이라고 한다.

'NetWork' 카테고리의 다른 글

VMware network  (0) 2012.07.10
tcphdr , tcphdr??  (0) 2012.07.09
ARP_Spoofing  (2) 2012.07.06
ICMP Protocol  (0) 2012.07.06
Wireshark_Network Analysis  (2) 2012.04.17

Socket Programming을 할때에 소캣을 생성하고 connect ,bind 등등 할때에 소캣에 IP, PORT를 넣어주어야 하는데 이때 미리 선언되어 있는 Socket 구조체에 넣어준다.

 

struct sockaddr_in

{

sa_family_t    sin_family;        //주소체계를 저장함.

uint16_t         sin_port;          //16 비트 TCP/UDP PORT 번호

struct in_addr  sin_addr;        //32비트 IP주소

char            sin_zero[8];      //사용되지 않음.

};

 

struct in_addr

{

in_addr_t    s_addr;        //32비트 IPv4 인터넷 주소

};

 

위의 자료형중에 uint16_t라던지 in_addr_t와 같은 자료형은 POSIX(Portable Operating System Interface)에 나와있는데, POSIX란, 유닉스 계열의 운영체제에 적용하기 위한 표준을 의미한다. 

따로 자료형을 정의해 놓은 이유는 확장성을 고려한 결과이다. int32_t라는 자료형은 이후에 int가 64비트로 표현되는 경우에도 4바이트 자료형임을 보장받을 수 있다. 즉 어떠한 경우에도 int32_t는 4바이트로 표현됨.

 

구조체 멤버 분석

 

sin_family

멤버sin_family에 적용할 주소체계 정보를 저장.

 

 

sin_port

16비트 PORT주소 정보를 저장한다. '네트워크 바이트 순서'대로 저장해야 한다.(빅 에디안)

 

sin_addr

32비트 IP주소 정보를 저장한다.  이역시 빅에디안 순서대로 저장.

 

sin_zero

특별한 의미없음.sockaddr 구조체와 일치시키기 위해 삽입된 멤버.

struct sockaddr{

sa_family_t    sin_family;     //주소체계 저장.

char             sa_data[14]; //주소 정보.

};

 

위의 구조체 멤버 sa_data에 저장되는 주소정보에는 IP주소와 PORT번호가 포함되어야 하고,이 두가지 정보를 담고 남은 부분은 0으로 채울 것을 요구한다.

sockaddr_in에 sin_zero가 존재하는 이유

하지만 이는 주소정보를 담기에 매우 불편한 사항이기 때문에 sockaddr_in이 등장한 것이다.

sockaddr_in구조체 멤버를 채우고 난뒤에 이때 형성되는 구조체 변수의 바이트 열이 요구하는 바이트 열이 되기 때문에 인자전달을 위한 형변환만 시켜주면 바로 요구사항을 채워줄수 있다.

따라서 sockaddr_in에 필요한 정보를 채우고 bind함수를 호출할 때에는 (struct sockaddr *)로 형변환을 시켜주면 간단하게 해결됨.

 

'Programming > Socket' 카테고리의 다른 글

클라이언트 IP 가져오기  (0) 2012.05.14
멀티프로세스 소스  (0) 2012.05.10
멀티프로세스 서버  (0) 2012.05.08
소켓의 옵션  (0) 2012.05.07
TCP server 함수호출 순서.  (0) 2012.04.25

파일 디스크립터

 

파일을 관리하기 위해 운영체제가 필요로 하는 파일의 정보를 가지고 있는 것이다. FCB라고 함.

FCB - File Control Block 이라고 하며 FCB에는 다음과 같은 정보들이 저장되어 있다.

 

파일 이름

보조기억장치에서의 파일 위치

파일 구조 : 순차파일, 색인 순차 파일, 색인 파일

액세스 제어정보

파일 유형

생성 날짜와 시간, 제거 날짜와 시간

최종 수정 날짜 및 시간

액세스한 횟수

 

결론은 파일디스크립터란 운영체제가 만든 파일 또는 소켓의 지칭을 편히 하기 위해서 부여된 숫자이다.

※파일디스크립터를 파일핸들이라고도 하는데, 핸들이라는 표현은 윈도우에서 사용되는 용어임.

기본적으로 파일 디스크립터는 정수형으로 차례로 넘버링 되고 0,1,2는 이미 할당되어 있어서 3부터 파일 디스크립터를 부여한다.

 

 

 

ex)

파일 입출력이나, 소켓에서 파일 디스크립터가 차례로 넘버링됨.

 

#include<stdio.h>
#include<sys/socket.h>
#include<fcntl.h>    //O_CREAT가 선언되있는 라이브러리

int main()
{
        int fd1,fd2,fd3;


        fd1 = socket(PF_INET,SOCK_STREAM,0);
        fd2 = open("test.txt",O_CREAT);
        fd3 = socket(PF_INET,SOCK_DGRAM,0);

 

        printf("file descriptor : %d\n",fd1);
        printf("file descriptor : %d\n",fd2);
        printf("file descriprot : %d\n",fd3);

 

        close(fd1); close(fd2); close(fd3);

 

        return 0;
}

 

'O.S' 카테고리의 다른 글

Synchronization Hardware  (0) 2012.04.27
Semaphore  (0) 2012.04.27
공유메모리 함수 - shmget , shmat , shmdt  (2) 2012.04.23
Process Scheduling - Multilevel Queue scheduling,Multilevel feedback Queue Scheduling  (0) 2012.04.22
Process Scheduling  (0) 2012.04.19

저번 포스팅 Critical section - 공유메모리 에서 pipe로 통신하는 방법 외에도 여러가지 방법이 있어서 그중, 공유메모리를 이용한 통신을 알아보도록 하자.

일단 기본적으로 프로세스간 통신을 위해 알아야 할 함수들이다.

 

int shmget(key_t key, size_t size, int shmflg); // key: 공유하는 키값, size:크기, shmflg:생성 및 접근, 성공하면 양의 정수, 실패 시 -1 리턴

 

shmflg 옵션들

1) IPC_CREATE

 

키에 해당하는 값이 없다면 새로 생성한다.

IPC_CREATE 값을 입력후 | 연산자를 덧붙여 허용권한 설정.

만약 있다면 무시하며, 접근권한을 설정해준다.

 

2)IPC_EXCL

 

공유 메모리가 이미 있다면 실패를 반환하고 접근 불가능.

이옵션을 제거해 주어야 기존 공유메모리에 접근할 수 있다.


void* shmat(int smId, const void* shm_addr, int flag); // smId:공유메모리 식별자, shm_addr:공유 메모리와 연결하고자 하는 프로세스 내부의 메모리.(프로그래머가 직접 정해주는 것보다 시스템에 의해 할당되는 것이 좋으므로 일반적으로 null(0)을 세팅) flag: 속성 설정(SHM_RND:공유메모리와 연결되는 프로세스 내부 어드레스를 시스템이 관리하도록 함 , SHM_RDONLY: 읽기 전용으로 메모리를 연결, SHM_REMAP:연결영역을 대체)
가상 메모리와 물리적메모리 영역을 연결해주는 함수.

int shmdt(const void* shm_addr);
프로세스가 작업을 끝내고 더 이상 메모리 공유가 필요 없을 때, 공유메모리와 연결된 프로세스 내부의 가상 메모리 연결을 해제.

 

공유메모리를 설정하면 공유메모리의 semid가 주어지는데 이 ID로 공유메모리를 식별하거나 찾아들어간다.

 

 

ipcs : 현재 공유메모리 보기.

ipcrm shm [shmid] : 공유메모리 제거.

 

간단한 예제를 보면서 사용법을 익히기로 한다.

 

shared.c

 

#include<stdio.h>
#include<stdlib.h>
#include<sys/shm.h>                //공유메모리 함수의 라이브러리

struct shared_use_st{               //some_text 배열을 공유메모리로 사용할 것임.
                int written_by_you;
                char some_text[2048];
};

int main()
{
        int shmid;
        void* shared_memory=(void*)0;
        int running=1;
        struct shared_use_st* shared_stuff;

        shmid = shmget((key_t)1234,sizeof(struct shared_use_st),0666 | IPC_CREAT);    

        //공유메모리생성
        if(shmid == -1){
                printf("Shmget Error\n");
                exit(1);
        }
        shared_memory = shmat(shmid,(void*)0,0);    //생성한 공유메모리를 shared_memory변수에 붙인다.
        if(shared_memory == (void*)-1)
        {
                printf("Shared_memory location Error\n");
                exit(1);
        }
        shared_stuff = (struct shared_use_st *)shared_memory;//형변환후 최종적으로 구조체를 공유메모리로 설정한다.
        shared_stuff->written_by_you = 0;
        while(running){
                if(shared_stuff->written_by_you)        //written_by_you ==1이면 입력받은내용이있으므로 출력후에 0으로 바꿔줌.
                {
                        printf("Wirten is : %s\n",shared_stuff->some_text);
                        sleep(rand()%4);
                        shared_stuff->written_by_you =0;
                        if(strncmp(shared_stuff->some_text,"end",3)==0)    // end를 입력하면 종료.
                                running=0;
                }
        }

        return 0;
}

 

 

shared1.c

 

#include<sys/shm.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct shared_use_st{
        int written_by_you;
        char some_text[2048];
};

int main()
{
        int running =1;
        void *shared_memory =(void *)0;
        struct shared_use_st* shared_stuff;
        char buffer[100];
        int shmid;

        shmid = shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);

        if(shmid==-1){
                printf("Shmid Error\n");
                exit(1);
        }
        shared_memory = shmat(shmid,(void*)0,0);
        if(shared_memory == (void*)-1)
        {
                printf("Shamt Error\n");
                exit(1);
        }
        printf("Memory located at %p\n",shared_memory);
        shared_stuff = (struct shared_use_st*)shared_memory;
        while(running)
        {
                while(shared_stuff->written_by_you==1)
                {
                        sleep(1);
                        printf("waiting for client...\n");
                }
                printf("Enter some text...\n");
                fgets(buffer,100,stdin);
                strncpy(shared_stuff->some_text,buffer,2048);
                shared_stuff->written_by_you=1;
                if(strncmp(buffer,"end",3)==0)
                {
                        running=0;
                }
        }
        return 0;
}

 

shared.c과 shared1.c가 서로 통신을 하면서 shared1.c에서 입력한 값을 shared.c에서  출력하게 끔하는 소스이다.

shm_com.h라는 라이브러리에 sturct shared_use_st구조체가 선언되어 있다는 것을 알게됬으나, Ubuntu 11.10버전에서는 이상하게 라이브러리가 존재하지 않아서 소스딴에서 전역변수로 넣어주었다. 공유메모리 어렵다 ...조금더 확실히 알고 가야할듯하다. 하지만 지금은 시험보기 3시간전ㅋㅋㅋㅋㅋㅋㅋㅋ

'O.S' 카테고리의 다른 글

Semaphore  (0) 2012.04.27
파일 디스크립터(File descriptor)  (0) 2012.04.24
Process Scheduling - Multilevel Queue scheduling,Multilevel feedback Queue Scheduling  (0) 2012.04.22
Process Scheduling  (0) 2012.04.19
Process Scheduling - Round_Robin  (0) 2012.04.19

Multilevel Queue scheduling

 

Multilevel Queue scheduuling은 기존의 FCFS or SJF or Priority의 방법은 Queue를 하나씩 두었던 반면에 이 Multilevel scheduling은 Queue를 여러개 두어 각각의 큐마다 우선순위를 두는 방식이다.

우선순위는 위의 System Process Queue가 가장 높고 밑의 Student Process가 가장낮다.

 

Multilevel Queue Scheduling은 각각의 큐가 서로다른 Priority를 가지고 있어서 기존의 Priority 알고리즘보다 조금 더 세밀한 프로세스의 관리가 가능하고 각각의 Queue마다 서로 다른 알고리즘 구현이 가능하다는 장점이 있지만, 프로세스가 한번 큐에 속하게 되면 다른 큐로 이동이 불가능 하다는 단점이 있다.  만약 student process에 대기중인 프로세스가 있지만, system Queue에 계속해서 프로세스가 들어온다면 student Queue에 있던 프로세스는 stavation 현상이 일어나게 된다.

※Stavation = 프로세스가 실행되지 못하게 계속 남게 되는 현상.

Priority 알고리즘에서는 Queue가 하나이기 때문에 Aging기법으로 해결하였으나, Multilevel Queue알고리즘에는 큐가 여러개이고 한번 속하면 다른 큐로 이동이 불가능 하기 때문에

 

Multilevel Feedback Queue Scheduling을 이용하여 문제를 해결하였다.

 

Multilevel Feedback Queue Scheduling

 

Multilevel Feedback Queue scheduling 은 위의 Multilevel Queue Scheduling 알고리즘을 확장한 개념으로, 프로세스가 큐를 이동할 수 있다는게 특징이다.

 

위처럼 Queue가 3개가 있다고 가정하자.

 

맨 위Queue의 우선순위가 가장 높고 맨밑의 우선순위가 가장낮다.

Multilevel feedback Queu Scheduling은 마지막큐를 제외하고는 time quantum을 두어서 실행시킨다.만일 첫번째 큐에 프로세스가 들어왔지만, 지정된 타임퀀텀내에 실행이 종료되지않으면 preemptive가 일어나게 되고 실행되던 프로세스는 두번째 Queue에 들어가게 된다. 만일, 두번째 Queue에서도 실행이 종료되지 않으면 마지막 FCFS Queue에 들어가게되며 실행이 종료된다.

하지만,  quantum=16인 Queue의 프로세스가 실행되던 도중에 첫번쨰 Queue에 프로세스가 들어오게 되면 Preemptive가 일어게 됨.

'O.S' 카테고리의 다른 글

파일 디스크립터(File descriptor)  (0) 2012.04.24
공유메모리 함수 - shmget , shmat , shmdt  (2) 2012.04.23
Process Scheduling  (0) 2012.04.19
Process Scheduling - Round_Robin  (0) 2012.04.19
Process Scheduling - Priority  (0) 2012.04.19

[Scheduling 기준척도]

 

 

CPU utilization  = CPU를 가능한 바쁘게 유지시키는지.

 

Turnaround time = 하나의 프로세스가 끝나는 시간.

 

Throughput = 시간 단위당 비슷한 프로세스가 몇개나 완료되는지.

 

Response Ratio(서비스시간+대기시간)/서비스시간 = 멀티태스크

 

Process Scheduling

 

CPU 스케쥴링 결정은 다음과 같은 네 가지의 경우에 발생 할 수 있다.

 

1. Process의 상태가 Runing -> Ready 상태로 전환 될때.

 

2. Process가 I/0 (입출력)요청을 하고 ready 상태로 전환 될때.

 

3. Process의 종료시.

 

4. Process의 상태가 Runing -> wait 상태로 전환 될 때.

다음과 같은 네가지 경우에서 3 ,4 상태의 경우 스케쥴링이 일어날 여지가 없지만, 1 ,2의 경우 프로세스를 임의로 상태를 전이시킬 수 있는데, 이러한 것을 Preemptive(선점)라 한다. 3 ,4의 경우에는 Nonpreemptive(비선점)라고 함.

nonpreemptive 스케줄링은 CPU에게 하나의 프로세스가 할당되면 그 프로세스가 I/O요청을 하여 빠져나오거나 종료 될 때까지 계속 프로세스를 실행 시키는 것이다.

preemptive스케줄링은 공유메모리 관련해서 문제가 일어난다.(프로세스의통신(공유메모리)참조.)

 

Process의 Scheduling에는 4가지 종류가 있는데

 

1. FCFS (First - come,First-serverd)

 

2. SJF (Shortest - Job - First)

 

3. Priority

 

4. Round - Robin

Round - Robin Scheduling

 

round - robin scheduling은 프로세스 마다 time quantum을 둔다.

※Time Quantum = 프로세스마다 CPU를 점유할 수 있는 시간을 정해 두는 것.

 

실행중이던 프로세스가 타임퀀텀에 의해 종료되면 Ready Queue의 제일 뒤쪽으로 옮겨진다.

Time Quantum이 너무 클 경우에는 FCFS Scheduling과 같은 알고리즘이 되고, 반면에 Time Quantum이 너무 작을 때에는 너무 잦은 Context-switch가 일어나 오버헤드가 발생, Time Quantum이 Context-switch보다 작을 때는 프로세스환경을 셋팅하다가 타임퀀텀이 끝나버려서 정작 프로세스의 실행을 하지 못하고 다시 CPU를 반환해야 한다.

일반적으로 Time Quantum = CPU Burst time 의 80%를 기준으로 한다.

 

만약 Ready Queue에 N개의 프로세스가 있고 Time Quantum 을 p라 한다면, 프로세스가 CPU를 점유하기 위한 최대 시간은 (N-1)*q이다. 

 

 

'O.S' 카테고리의 다른 글

Process Scheduling - Multilevel Queue scheduling,Multilevel feedback Queue Scheduling  (0) 2012.04.22
Process Scheduling  (0) 2012.04.19
Process Scheduling - Priority  (0) 2012.04.19
Process Scheduling - SJF  (0) 2012.04.19
Process Scheduling - FCFS  (0) 2012.04.19

+ Recent posts