Monitor 를 이용한 상호 배제의 문제를 생산자-소비자(한계 버퍼) 문제에 적용하여 baci툴을 이용하여 구현한 것.

목표 및 내용

수업 시간에 배웠던 Monitor를 이용 상호 배제가 되도록 구현을 하는것 입니다. Monitor는 세마포어를 이용한 정확한 프로그램의 작성이 어렵기 때문에 고안된 것입니다. 기능은 세마포어와 동일하나 세마포어보다 제어가 더 쉽습니다. baci툴에서는 Hoare 의 방법이 이용됩니다. Monitor 의 구성요소는 C 언어에서의 구조체와 비슷하고 객체 언어에서는 클래스의 개념과 유사합니다. 구성 순서는 지역변수와 하나이상의 procedure 그리고 초기화 하는 문장의 순서대로 작성이 됩니다.  

모니터는 한 번에 하나의 프로세스만 모니터 내에 존재하게 하고, 공유데이터 보호를 위해서 모니터 구조 내에다가 공용변수를 둠으로써 상호 배제를 보장합니다. 모니터는 조건 변수를 통해서 조건이 만족될때 까지 대기하고 조건이 만족하여 가용 상태가 되면 대기 프로세스가 일을 수행 할 수 있도록 재진입 하게 됩니다.

조건변수에 적용하는 변수 두개는 wait연산과 signal연산이 있는데 baci 툴에서는 waitc, signalc 로써 사용 합니다.

 

소스코드

const int N = 10; //버퍼 변수 갯수를 정하는 변수

const int TRUE = 1; //참값

const int FALSE = 0; //거짓 값

monitor monSemaphore{ // baci cmimi ppt 의 예문을 토대로 작성을 하였습니다.

int buffer[N]; //공용변수

int nextin; //변수를 쓰고난 다음 변수를 지정하는 변수

int nextout; //사용한 변수를 나타내는 변수 사용하고나면 다음쓸변수로 값이 증가.

int count; //버퍼의 갯수를 세어서 공용버퍼가 비었는지 가득 찼는지를 비교 할 때 사용 하는 변수.

condition notfull; //조건변수 가득 찼음을 알리는 변수

condition notempty; //조건변수 비었음을 알리는 변수

void monP(int x) //생산자

{

if(count == N) //버퍼를 사용한 갯수가 버퍼의 크기랑 같으면

{

waitc(notfull); //대기상태로 빠트림

cout<<"-- buffer is full --"<<endl;

}

else //버퍼가 가득차지 않으면 else를 수행

{

buffer[nextin] = x; //외부에서 인자 값으로 보낸 값을 변수에 넣음.

cout<<nextin<<" buffer input "<<x<<" item"<<endl; //출력문

nextin = (nextin+1)%N; //다음 변수로 증가 %연산자는 버퍼를 환형으로 사용하 //기 위함

count = count+1; //한칸 생생했으므로 카운트를 증가시킴

signalc(notempty); //혹시 버퍼가 비어서 잠들어있는 소비자가 있을경우 깨움.

}

}

void monV(int x) //소비자

{

if(count == 0) //버퍼가 비어 있다면 생산자가 버퍼에 값을 넣을때 까지 대기상태로 빠짐.

{

waitc(notempty);

cout<<"-- buffer is empty --"<<endl;

}

else //버퍼가 빈 상태가 아니면 소비를 진행함.

{

x = buffer[nextout]; // 버퍼에 있는 값을 x에 담음

cout<<nextout<<" buffer consume "<<x<<" item"<<endl; //출력문

nextout = (nextin+1)%N; //이 역시 환형 변수로 사용하기위해 %연산자를 이용.

count = count-1; //하나를 소비하였으므로 카운트 값을 하나 줄여줌.

signalc(notfull); //혹시 버퍼가 가득차서 대기중인 생산자가 있으면 깨워줌.

}

}

init //모니터 안의 변수 초기화 문.

{

nextin = 0;

nextout = 0;

count = 0;

}

}

void producer(void) //생산자 스fp드

{

int x = 0; // x의 값을 제품번호의 개념으로 인자 값으로 넘겨줌.

while(TRUE)

{

monP(x);

x = x+1;

}

}

void consumer(void) //소비자 스레드

{

int x;

while(TRUE)

{

monV(x);

}

}

void main()

{

cobegin //생산자와 소비자를 병행 수행

{

producer();

consumer();

}

}

결과화면

 

'Study > OS' 카테고리의 다른 글

Semaphore 구현하기  (2) 2012.05.04
Test-And-Set  (0) 2012.04.27
Bakery 알고리즘  (1) 2012.04.22
Peterson 알고리즘  (0) 2012.04.22
jBACI 사용법  (0) 2012.04.15

Semaphore 를 이용한 상호 배제의 문제를 생산사 - 소비자(한계 버퍼) 문제에 적용하여 baci 툴을 이용하여 구현을 한 것이다.

목표 및 내용

수업 시간에 배웠던 semaphore를 이용 상호 배제가 되도록 구현을 하는것 입니다. 우선 semaphore는 이 때 까지 의 busy waiting 이 계속 해서 cpu의 자원을 사용 하는 문제를 해결하기위하여 다른 프로세스가 임계 구역을 사용하고 있을 때, 진입을 하게 되면 블록 상태가 되고, 이미 임계구역에 들어가 있던 프로세스는 임계구역을 탈출 하면서, 신호를 보내주어 블록 되어있던 프로세스를 깨웁니다. 이러한 방법으로 cpu자원의 낭비도 없애고 상호배제 도 가능하게 할 수 있습니다.

semaphore wait signal 구조

 

2진 세마포어

 

세마포어 연산의 정의

알고리즘

소스코드

const int N = 10; // 버퍼의 공간을 잡을 상수

const int TRUE = 1; // TRUE = 1을 나타내는 상수

const int FALSE = 0; // FALSE = 0을 나타내는 상수, 세마포어에서 쓰이지는 않음.

semaphore mutex = 1; //이진 세마포어 를 구현하기위한 세마포어 변수 초기 값을 1로 설정

semaphore empty = N; //빈공간이 얼마만큼 남았는지 계산하는 세마포어 변수 초기 값을 버퍼의 갯수 만큼 설정.

semaphore full = 0; //생산품이 얼마만큼 차있는지 계산하는 세마포어 변수 초기값을 0으로 설정.

int buffer[N]; // 임계구역 공용 변수

void producer(void) // 생산자

{

int item = 1; //생산자가 1이라는 item을 생성함.

int i = 0; //공용번수의 자리번호를 정하기 위함.

int Num; //공용변수 배열에 값을 지정하기 위함. 10까지 지나면 다시 1로 돌아오기 때문에 % //연산을 해야 함.

while(TRUE) //무한 생산

{

wait(empty); //먼저 빈 공간을 할당 받고, 빈공간이 남아있다면 블록 되지않고 통과함

// cout<<"Mutex : "<<mutex<<" Empty : "<<empty<<" Full : "<<full<<endl<<endl;

wait(mutex); //2진 세마포어로 임계구역을 쓰는 프로세스가 있는지를 확인.

//초기값이 1이므로 다른 프로세스가 먼저 사용하지 않았다면 0으로 만들고 진입.

cout<<"Insert item "<<i<<" buffer place"<<endl; //임계구역에 들어왔음을 출력.

cout<<"Mutex : "<<mutex<<" Empty : "<<empty<<" Full : "<<full<<endl; //세마포어 번호

Num = i%N; //나누기 연산자를 쓴 것은 9 다음 카운트로 10이아닌 0으로 돌아가게 하기위 //함. 앞에 test_and_set구현의 이웃 프로세스에게 자리 양보 의 응용.

// if(buffer[Num] == 0)

// {

buffer[Num] = item; // 공용변수에 생산품을 집어넣음

i = (i+1)%N; // 공용변수의 다음 자리로 이동

cout<<"buffer["<<Num<<"] 's insert_item is "<<buffer[Num]<<endl<<endl;

// }

// else

// {

// cout<<"buffer["<<Num<<"] is not empty"<<endl;

// }

//여기서 if else 문을 썼던 것은 %연산자로 인해 환형 큐 형식으로 되어서 만약 공용번수에 모든 값을 집어 넣고

//나서도 또 넣으려고 시도 할 때 예외처리 하려고 했었으나, 이렇게 하지 않아도 empty 와 full 세마포어 로 인해

//블록이 되므로 굳이 쓰지 않아도 됩니다.

signal(mutex); //임계구역을 빠져나감을 알림 mutex값을 +1 증가 시켜주고 신호를 보냄.

// cout<<"Mutex : "<<mutex<<" Empty : "<<empty<<" Full : "<<full<<endl<<endl;

signal(full); //full 값을 증가시켜줌으로 소비자가 임계구역이 비어있지 않다는것을 알림.

}

}

void consumer(void) //소비자

{

int item = 0; //소비자가 소비를 하고나면 원래 초기 빈값을 넣어줌

int i = 0; //공용번수의 자리번호를 정하기 위함.

int Num; // 역시 % 연산자로 인해 연산을 하여 값을 넣어야 하므로 변수를 생성함.

while(TRUE) //무한 소비

{

wait(full); //full 세마포어 변수가 0일시 공용변수가 비어있으므로 소비 할 수 없고 블록 됨.

// cout<<"Mutex : "<<mutex<<" Empty : "<<empty<<" Full : "<<full<<endl<<endl;

wait(mutex); //2진 세마포어로 임계구역을 쓰는 프로세스가 있는지를 확인.

cout<<"Remove item "<<i<<" buffer place"<<endl; //임계구역 진입을 출력함

cout<<"Mutex : "<<mutex<<" Empty : "<<empty<<" Full : "<<full<<endl; //세마포어 번호

Num = i%N; // 위의 생산자에서의 설명과 같이 9 -> 0으로 돌리기 위해 %연산을 함.

// if(buffer[Num] == 1)

// {

buffer[Num] = item; // 소비자가 소비 후 버퍼를 빈상태로 돌림.

i = (i+1)%N; //공용변수의 다음 자리로 이동.

cout<<"buffer["<<Num<<"] 's item remove result is "<<buffer[Num]<<endl<<endl;

// }

// else

// {

// cout<<"No product in"<<"buffer["<<Num<<"]"<<endl;

// }

//여기서 if else문을 썼던겄도 위에 생산자에서의 이유와 동일함.

signal(mutex); //임계구역을 빠져 나감을 알림.

// cout<<"Mutex : "<<mutex<<" Empty : "<<empty<<" Full : "<<full<<endl<<endl;

signal(empty); // 하나를 소비했으므로 빈공간이 한개 더 늘었음을 알려줌.

}

}

void prod(void) //생산자 스레드

{

producer();

}

void consum(void) // 소비자 스레드

{

consumer();

}

void main()

{

int i;

for(i=0; i<N; i=i+1) // 공용변수의 초기화

{

buffer[i] = 0;

}

cobegin // 병행 수행을 하기위한 cobegin문.

{

prod();

consum();

}

}

실행결과 화면

 

 

'Study > OS' 카테고리의 다른 글

Monitor 를 이용한 생산자-소비자 구현  (0) 2012.05.04
Test-And-Set  (0) 2012.04.27
Bakery 알고리즘  (1) 2012.04.22
Peterson 알고리즘  (0) 2012.04.22
jBACI 사용법  (0) 2012.04.15

앞서 했던 피터슨 알고리즘 은 두 프로세스간의 상호 배제 가 가능하게 하였고, bakery 알고리즘 에서는 N개 이상의 프로세스의 상호 배제를 티켓과 프로세스 번호를 이용하여 구현 하는 방법 이다. 이번 Test-and-set 을 이용한 상호 배제는 atomic function 을 사용해서 함수의 조건을 비교 할 때엔 한 프로세스가 점령을 하면 다른 프로세스가 개입을 할 수 없도록 선점해서 사용하는 개념으로 상호 배제를 하는 기법 이다.

 

알고리즘

 

 

 

 

Jbaci로 구현한 소스코드

const int TRUE = 1; //TRUE 를 1로 정의

const int FALSE = 0; //FALSE 를 0으로 정의

const int PCOUNT = 5; // process 의 개수 정의.

int lock = 0; // 공용 lock 변수.

int waiting[PCOUNT]; //프로세스 번호가 가까운 사람에게 자리를 주기위하여 waiting배열 선언.

int n; // 연산을 위한 공용 변수 n

atomic int Test_and_set(int& loc) // atomic 함수로 함수에 진입하고 나면 다른 프로세스가 간섭 할수 없다.

{ // 인자 값을 &를 써서 주소 값으로 받은 이유는 공용변수 lock 을 직접적으로

int TAS; // 호출 할 경우 함수 밖의 값을 불러 오는 것이기 때문에 다른 프로세스의 간섭

TAS = loc; // 이 일어날 수 있다.

loc = TRUE; // lock 변수의 값을 다른 TAS변수에 저장하고 lock변수 안의 값을 1로 세팅을 한 //다.

return TAS; // 그리고 초기의 lock변수 의 값인 TAS의 값을 반환을 한다.

}

void enter_region(int i) //임계구역의 진입을 조건에 의해서 각 프로세스가 상호 배제가 되도록 하는 함수

{

int j; // for 문을 위한 변수

// int key = FALSE; // 키 값을 선언하고 초기화를 해준다.

// 현제 key 값이랑 밑의 와일문을 주석 처리 해놓았는데 이유는 아래 소스분석

waiting[i] = TRUE; //에서 설명 하겠습니다. waiting[]배열에 자신의 프로세스번호에 해당하는 곳에

// key = TRUE; // 값을 참으로 설정 한다.

while( (waiting[i]) && Test_and_set(lock) ) // 여기서 waiting값은 참이므로 뒤의 Test_and_set함수

{ //에서 참이 나오면 대기상태가 되고 거짓이 나오면

} //while 문을 통과하여 임계구역에 진입하게 됩니다.

// while( (waiting[i]) && key ) // 주석문은 원 알고리즘을 보고 처음 코딩했던 소스입니다.

// {

// key = Test_and_set(lock); //Test_and_set의 함수의 리턴 값을 담아 다음 조건에서 비교를함.

// }

waiting[i] = FALSE; // 임계구역에 진입 했으므로 waiting변수를 0으로 해준다.

// 변수를 0으로 해주는 이유는 leave_region에서 인근 프로세스에게

//임계구역을 넘겨줄 때 쓰임.

cout<<i<<" process is enter_region"<<endl; //프로세스가 들어왔다는 문구 출력

n=0; // 공용변수 n의 초기화

cout<<i<<" process's calculate start!"<<endl; // 프로세스 계산 시작 문구 출력

for(j=0; j<5; j=j+1) //1씩 더하는 연산

{ //여기서 간섭이 생긴다면 n이 공용변수이므로

n = n+1; //n의 값이 5가 나오지 않을 것임.

}

cout<<i<<" process's calculate result is "<<n<<endl; // 계산 결과를 출력하는 문구.

}

void leave_region(int i) // 일을 다 하고 임계구역을 나간후에 연산하는 함수

{

int j; //다른 프로세스 아이디를 담을 변수

j = (i+1) % PCOUNT; // 현재 프로세스에서 +1을 하고 전체 프로세스 수로 나누어 남은 값. 즉

// 현재 계산 하고난 다음번호의 프로세스 번호를 담음. ex) 0->1

while( (j != i) && !(waiting[j]) ) //j와 i가 같다면, 주변 프로세스 한 바퀴 검사 한 것이므로 더 이상

{ // 검색하지 않는다. 그리고 waiting에 0이 있다면 이미 실행한 프로

j = (j+1) %PCOUNT; //세스 이므로 다음 프로세스로 넘긴다 .

} // while 문장 안은 다음의 뒷 프로세스를 검색하는 것임.

if( j==i ) // 한 바퀴다 돌아도 임계구역에 들어갈 프로세스가 없다면

{ //lock 공용변수를 풀어주고 끝낸다.

lock = FALSE;

}

else //누군가 인접한 프로세스가 대기하고있다면 그 프로세스에게 먼저 기회를 준다.

{

waiting[j] = FALSE;

}

cout<<i<<" process is leave_region"<<endl; // 임계구역을 탈출했다는 문구

}

void process(int i) // thread

{

{

enter_region(i);

leave_region(i);

}

}

void main()

{

int i;

for(i=0; i<PCOUNT; i=i+1) // waiting배열을 초기화 함.

{

waiting[i] = FALSE;

}

cobegin // 병행으로 프로세스 5개를 실행함.

{

process(0);

process(1);

process(2);

process(3);

process(4);

}

}

baci에서 실행화면

 

Jbaci에서 실행화면

 

'Study > OS' 카테고리의 다른 글

Monitor 를 이용한 생산자-소비자 구현  (0) 2012.05.04
Semaphore 구현하기  (2) 2012.05.04
Bakery 알고리즘  (1) 2012.04.22
Peterson 알고리즘  (0) 2012.04.22
jBACI 사용법  (0) 2012.04.15

운영체제 수업시간에 공부했었던 빵집알고리즘(Bakery Algoritm) 에 관한 설명이다.

내용

앞서 했던 피터슨 알고리즘 은 두 프로세스간의 상호 배제 가 가능하게 하였고 이번 bakery 알고리즘 에서는 N개 이상의 프로세스의 상호 베제 가 되도록 구현하는 방법이다. 간단하게 빵집 알고리즘을 설명을 하면 프로세스에 먼저 온 순서대로 번호표를 부여하고, 그 번호표가 우선인 프로세스부터 작업을 시켜주는 것이다. 만약 두 프로세스가 동시에 접근을 하여 번호표가 같아진다면, 프로세스 번호가 낮은 순서로 우선순위를 정하여, 상호간에 연산에 있어서 간섭이 일어나지 않도록 하는 방법이다.

다음은 알고리즘이다.

 

Jbaci를 이용해서 구현해본 소스코드이다.

const int TRUE = 1; // TRUE변수를 1로 상수화

const int FALSE = 0; // FALSE변수를 0으로 상수화

const int PNUM = 10; // 프로세스의 생성 개수를 상수화 하여 프로세스의 개수가 늘고 줆에 있어 이수치만 //수정하면 된다.

const int N = 5; //연산의 계산을 하기위한 상수

int n; //공용 변수

int number[PNUM]; //프로세스의 티켓의 값을 저장할 배열

int choosing[PNUM]; //프로세스가 번호표를 뽑았는지 아닌지를 기억하는지를 저장할 배열

int MAX() //티켓을 나눠주는 함수. 티켓 이 저장되어있는 number배열의 값들을 조사하여서 가장

{ //큰 값을 반환하여 주는 역할을 합니다.

int i; // for문을 사용하기위한 변수

int j; // for문을 사용하기위한 변수

int MAXNUM = 0; //가장 큰 번호표를 담을 변수 초기값을 0으로 설정해준다. 아무도 번호표가

for(i=0; i<PNUM; i=i+1) // 없을시 0을 반환하기 위해.

{ // 프로세스의 개수만큼을 비교한다.

for(j=0; j<PNUM; j=j+1)

{

if(number[i]<number[j]) //2중 for문을 이용하여 각자리를 비교 하고,

{

MAXNUM = number[j]; //가장 큰값을 MAXNUM변수에 저장한다.

}

}

}

return MAXNUM; //MAXNUM 변수를 반환해준다.

}

int NUM(int j, int i) //각 프로세스의 티켓번호를 비교하여 결과값을 돌려주는 함수.

{

if(number[j] < number[i]) // i프로세스가 현제 실행하는 프로세스 이므로 i 프로세스의 티켓이

{ // 더 낮을 때 루프를 탈출해야 하므로 number[j]<number[i]조건에서 참

return 1; // 일때는 1을 리턴 해주어 대기하게 만든다.

}

else if(number[j] > number[i]) // 위와 반대로 i프로세스의 티켓이 더 작을 때는 while루프를 빠져나갈

{ //수 있도록 0을 리턴해준다.

return 0;

}

else // 그리고 나머지경우는 두 프로세스간 티켓번호가 같을때 인데,

{ //이렇게 번호가 같을때는 두프로세스의 번호를 비교를 한다.

if(j<i) // 역시 i 프로세스가 현제 실행하는 프로세스이므로 i 프로세스의

return 1; //번호가 더 높을 때는 대기 상태를 가져야 하므로 1을 반환해주고,

else if(j>i) // 번호가 더 낮을 때는 0을 반환해주어 while루프를 빠져나가도록

return 0; // 해준다.

}

}

void enter_bakery(int i) //빵집알고리즘의 시작

{

int j; // 현제프로세스와 비교할 다른 프로세스들의 번호를 지정할 변수.

int k; // 조건을 통과하여 프로세스가 일을 수행 할 때 계산연산 for문을 위한 변수

choosing[i] = TRUE; // 티켓을 받기 전 의 상태를 저장.

number[i] = MAX()+1; // MAX함수를 통해서 이미 발부된 티켓 중 가장 높은 값의 다음값을 받는다.

choosing[i] = FALSE; // 티켓을 받은 후 의 상태를 저장.

for(j=0; j<PNUM; j=j+1) //이for문으로 모든 프로세스 티켓 과 프로세스번호로 통과 가능한지를 검사함

{

while(choosing[j]) //이 while 문에서 프로세스가 티켓을 받았는지를 검사함.

{ // 티켓을 받지 않았으면 대기상태로 빠짐.

// cout<<j<<" Process is Waiting until get a ticket"<<endl;

} //출력문은 출력 할 때 출력창이 너무 지저분해져서 주석처리 하였습니다.

while( (number[j] != 0) && (NUM(j, i)) ) // 이 while 문에서 티켓의 번호를 비교 검사함.

{ // 혹시 티켓의 번호가 같다면 NUM 함수 안에서 프로세스 번호를 비교함.

// cout<<j<<" Process is Busy Waiting"<<endl;

} //이 출력문 역시 출력창이 너무 지저분해져서 주석처리하고 출력하였습니다.

}

cout<<i<<"process's tiket"<<number[i]<<endl; //현제 수행하고 있는 프로세스의 티켓번호를 출력

n = 0;

cout<<i<<" process is calculating.."<<endl; //1을 5번 더하는 연산을 함

for(k=1; k<=N; k=k+1)

{

n = n+1;

}

cout<<i<<" process's calculate result is "<<n<<endl; // 완료된 결과를 보여줌.

}

void leave_bakery(int i) //프로세스가 연산을 하고나면 Busy Waiting중인 프로세스를 풀어주는 함수

{

cout<<i<<" process is calculate complete"<<endl;

number[i] = 0; //연산을 다 한 프로세스의 티켓을 0으로 바꾸어주면 while문의 number[j] !=0

} // 조건에서 false가 되므로 Busy Waiting상태가 풀리게 됨.

void process(int process) //일꾼의 역할을 하는 스레드

{

enter_bakery(process);

leave_bakery(process);

}

void main() //메인 함수

{

int i;

for(i=0; i<PNUM; i=i+1) // 처음의 number[i]배열과 choosing배열을 초기화 합니다.

{

number[i] = 0;

choosing[i] = TRUE;

}

cobegin

{

process(3); //10개의 프로세스를 병행 수행합니다.

process(2);

process(1);

process(0);

process(4);

process(5);

process(6);

process(7);

process(8);

process(9);

}

}

소스 해석

각 프로세스가 병행 수행을 하면서 조건에 따라 자신의 차례가 되었을 때만 일을 하게 되고 나머지 프로세스는 Busy Waiting 상태로 대기를 한다. 그리고 연산중인 프로세스는 연산을 완료 하고 나면 자신이 연산을 완료하였다고 알려주어 Busy Waiting상태에 들어 가 있는 프로세스들을 깨워 다음차례의 프로세스가 실행할 수 있도록 해준다.

실행결과

10개 프로세스 생성시

5개 프로세스 생성시

 

'Study > OS' 카테고리의 다른 글

Semaphore 구현하기  (2) 2012.05.04
Test-And-Set  (0) 2012.04.27
Peterson 알고리즘  (0) 2012.04.22
jBACI 사용법  (0) 2012.04.15
JBACI  (0) 2012.04.14

운영체제 수업시간에 공부했었던 피터슨 알고리즘에 관한 내용이다.

내용

병행 프로세스에서 순서를 지켜서 프로세스가 연산을 할 때 경고 변수와 잠금 변수를 사용하여, 간섭이 일어나지 않도록 하기 위한 알고리즘을 소스코드로 구현합니다.

미리 한번 해보았던 예제 코드의 for문으로 변수의 값을 1씩 5번 증가 시키는 것을 사용하여, 프로세스가 연산하는 값들을 출력하게끔 구현 하여 보았다.

 

Jbaci를 이용하여 테스트한 소스코드

const int FALSE = 0; // FALSE 값을 0으로 정의

const int TRUE = 1; // TRUE 값을 1로 정의

const int N = 2; //

const int m =5; // 각 프로세스가 하는 연산 횟수를 지정하는 변수

int turn; // 자신의 턴을 정하는 변수

int interested[N]; // 상대편의 연산 수행의 끝을 알 수 있는 배열

void leave_region(int process) //leave_region함수는 한 프로세스가 임계구역에 들어가서 수행을 다 한 후

{ //자신이 임계구역에서 나갔음을 알려주기 위한 함수.

cout<<process<<" process is calculate complete"<<endl; // 연산이 끝났다는 출력문 작성.

interested[process] = FALSE; //자신의 interested배열의 값을 FALSE로 바꿔줌으로써 상대편 프로세스의

} //busy Waiting 상태를 풀어 다음 연산을 실행 할 수 있도록 함

void enter_region(int process) //한 프로세스가 실행되고 나면 조건들을 비교하여, 연산 수행 중에 다른 프로세스

{ //가 연산하려고 접근을 할 때, 연산이 완료 될 때까지 while문에서 잡아두는 함수.

int n=0; // 연산을 위한 변수

int i; // 연산을 위한 변수

int other; // 상대편 프로세스 아이디를 담는 변수

other = 1-process; //두 프로세스가 0과1로 되어있으므로, 이 연산으로 상대편프로세스번호를 // 담을 수 있다.

interested[process] = TRUE; //interested의 자신의 번호를 TRUE로 만들어서, 다른 프로세스가 접근을 //할 때 while문의 (interested[other] == TRUE) 부분을 참을 만들어 //waiting 상태로 빠질 수 있게 만든다.

turn = process; //이 trun 변수 로 인하여 둘 다 busy waiting 상태로 빠지는 것을 방지한 한

//다. 두 프로세스가 동시에 접근을 하였을 때, interested값들도 다 TRUE가 //될 것이고, turn 변수도 자신의 이름을 쓰겠지만, turn 은 공용변수라서 조 //금이 라도 늦게 기록한 프로세스 값이 나오게 되고, 그렇다면 그 이외의 프 //로세스 가 진입을 할 수 있게 되고, 늦게 쓴 프로세스는 while 문에 의해 //busy waiting 상태에 빠지게 된다.

 

while( (turn == process) && (interested[other] == TRUE) ) //이 while 문에서 조건이 FALSE 가

{ //될 때 아래 연산을 수행 할 수 있다.

cout<<"["<<process<<" process is Wating...]"<<endl; // 대기 중인 프로세스를 알리는

} // 출력문.

cout<<"enter process is "<<process<<" process"<<endl; //while 문을 통과하여 연산을 시작한

//프로세스를 알리는 출력문.

cout<<process<<" process's calculate"<<endl;

for(i=1; i<=m; i=i+1) // 간단한 더하기 연산을 하는 for문

{

n = n+1;

cout<<process<<" process"<<" n = "<<n<<" i = ";

cout<<i<<" "<<process<<" process"<<endl;

}

cout<<process<<" process's calculate result is "<<n<<endl; //연산의 결과를 알려주는 출력문.

}

void process(int process) // 일을 하는 스레드

{

enter_region(process); //프로세스가 enter_region을 실행후 leave_region을 실행하여 다음 프로세스가

leave_region(process); //진입 할 수 있도록 만들어줌

}

void main()

{

int j;

for(j=0; j<N; j=j+1) // 처음 interested값을 0으로 초기화 함.

{

interested[j] = 0;

}

cobegin

{

process(0); // 두 개의 프로세스를 병행적으로 수행하기 위하여 cobegin을 사용하여

process(1); // 프로세스 두 개를 생성.

}

}

소스 해석

프로세스를 병행 실행을 할 수 있도록 cobegin 함수를 사용하여 일꾼에 해당하는 프로세스를 2개 생성합니다.

그리고 각각의 프로세스는 일을 수행하기 전에 enter_region에 들어가서 각 조건을 확인하고 while문안의 조건 값이 FALSE 가 될 때 연산을 실행합니다. 한 프로세스가 진입을 한 후에는 다른 프로세스는 진입을 할 수 없게 되며, 앞의 프로세스가 연산을 완전히 완료한 후 leave_region 함수를 통하여 끝을 알려주면, 연산을 할 수 있도록 하여, 공용 변수 사용함에 있어서 병행으로 수행되는 두 프로세스가 연산함에 있어 서로의 간섭으로 인해 결과 값이 틀어지는 것을 방지 하게 됩니다. 각각 수행되는 상세 부분은 주석으로 설명을 달아놓았습니다.

실행화면

 

 

'Study > OS' 카테고리의 다른 글

Test-And-Set  (0) 2012.04.27
Bakery 알고리즘  (1) 2012.04.22
jBACI 사용법  (0) 2012.04.15
JBACI  (0) 2012.04.14
BACI 툴  (0) 2012.04.14

이전에 올려둔 jBaci 툴을 사용하는 방법을 정리 ㅎ

이전에 올려둔 jbaci파일을 다운 받아서 압축을 풀면 run.bat파일이 있다. 그 파일을 실행하면 CMD 창과 함께 다음과 같은 화면이 나온다.

 최초 실행화면  

여기서 에디트에다 테스트 소스를 다음과 같이 입력해본다.

cobegin 문은 병렬로 프로세스들을 실행할때 사용하는 구문이다.

작성이 완료 되었으면 저장을 하는데 저장 할 때, 파일명.cm으로 저장을 한다

 

저장이 된후에 컴파일 을 눌러주면 소스가 이상이 없을시 다음과 같은 문구가 와 CMD창에도 변화가 생긴다. 그리고 .cm이 있는 폴더에 파일명.lst와 파일명.pco 파일이 생성이 된다.

 

제대로 완료가 되었으면 Run 탭을 눌르면 다음과 같은 창이 나온다.

 

Go 버튼을 눌르면 실행이 되는데 옆에 Processes 탭에서 각 프로세스를 더블클릭하면 다음과 같이 각 프로세스별 상황이 다 출력된다.

참고 ) 디버그 하는방법

1.  Run화면에서 Step Pcdoe 를 눌르면 한스텝씩 계속해서 진행이된다.

2. Go를 누른후 Pause를 눌르고 Step Source를 눌르면 한스텝씩 진행이된다.

'Study > OS' 카테고리의 다른 글

Test-And-Set  (0) 2012.04.27
Bakery 알고리즘  (1) 2012.04.22
Peterson 알고리즘  (0) 2012.04.22
JBACI  (0) 2012.04.14
BACI 툴  (0) 2012.04.14

 

jbaci1-4-5.zip

baci 툴을 더 쉽게 사용할수 있도록 만든

Jbaci 툴입니다.

'Study > OS' 카테고리의 다른 글

Test-And-Set  (0) 2012.04.27
Bakery 알고리즘  (1) 2012.04.22
Peterson 알고리즘  (0) 2012.04.22
jBACI 사용법  (0) 2012.04.15
BACI 툴  (0) 2012.04.14

 

badosxe-2005Nov09.zip

 

BACI 툴 입니다. 운영체제 교육 자료

'Study > OS' 카테고리의 다른 글

Test-And-Set  (0) 2012.04.27
Bakery 알고리즘  (1) 2012.04.22
Peterson 알고리즘  (0) 2012.04.22
jBACI 사용법  (0) 2012.04.15
JBACI  (0) 2012.04.14

+ Recent posts