관리 메뉴

개발자비행일지

C언어로 프로세스 스케줄러 만들기 본문

▶ 알고리즘

C언어로 프로세스 스케줄러 만들기

Cyber0946 2020. 3. 12. 15:01

https://kim-hoya.tistory.com/22

 

CPU 스케줄링 시뮬레이터 C로 만들기

호야의 블로그 [C] 운영체제-CPU 스케줄링 시뮬레이터 만들기 올해 수행했던 운영체제 short term job에서 일어나는 CPU 스케줄러를 구현하고 확인해보겠습니다. C를 이용하였으며 리눅스 환경에서 구현하였습니다..

kim-hoya.tistory.com

이글은 위의 블로그에서 공개한 내용을 바탕으로 학습하면서 소스코드를 바탕으로, 윈도우 환경에서 동작하도록 재구성했고, 초기화 선언 및 오류를 발생하는 부분을 수정하여 윈도우에서 동작하도록 작성한 코드 입니다.

개발환경은 devc++ 을 사용하였습니다.

devc++을 사용할 때는 아래 사이트를 통해서 코드 내용을 복사하고 붙여 쓰기를 한후 Options에서 

C Style을 선택하고, Tabify 버튼을 눌러서 보기 좋게 바꿔 줄 수 있습니다.

https://tools.arantius.com/tabifier

 

Tools - Tabifier (HTML and CSS code beautifier) - Arantius.com

Tabifier The tabifier is a tool to properly indent computer code. The style it produces is a mix of my personal preferences for indentation plus what I could manage to make a program produce from dirty source. The tabifier currently supports CSS, HTML, and

tools.arantius.com

먼저 진행하기 앞서서 필요한 배경 내용으로 구조체 포인터에 대해서 학습하고 해당 글을 보며 학습했다. 

구조체포인터

여기서 주의해야 할 점은 포인터는 어떤 변수의 주소를 담아서 가리키는 변수이다. 

이는 구조체 포인터도 마찬가지다. 구조체 포인터는 struct [구조체이름] *포인터명칭; 으로 선언할 수 있는데, 

여기서 구조체 포인터는 구조체를 가리키는 포인터이지 절대 구조체가 아니다. 

이 말은 구조체를 먼저 가지고 있고 그 다음 포인터가 그 구조체를 가르킬 수 있다는 것이다. 

위에서 참고한 내용의 글에서 작성한 소스코드는 이 부분이 않되어 있어서, 이 부분을 수정하여서 먼저 구조체 배열을 선언하고 그걸 통해서 참조하는 방식으로 변경해서 윈도우에서 작동 하도록 바꿨다.

구조체 포인터는 다음과 같이 선언하며 실행결과는 아래와 같다.

위처럼 구조체 포인터를 이용하면 값을 대입하고, 그 값을 사용할 수 있다. 이 때, 주의할 점은 포인터를 사용할 때

*ptr이 아니라 (*ptr)로 괄호를 이용해서 사용해야 한다는 점이다.

. 호출자도 하나의 연산자이기 때문에, *ptr.age를 이용하면 구조체가 아닌 포인터 변수를 구조체로 보고 포인터변수를 참조하려고 하기 때문에 오류가 발생한다. 

다시 말하면 포인터는 구조체를 가리키는 포인터이지 구조체가 아니다. 

하지만 매번 쓰기엔 귀찮다. 이를 위해서 등장한게 -> 연산자이다 이걸 사용하면 괄호를 사용하지 않아도 포인터가 

가르키는 주소로 가서 구조체를 참조한다. 

중첩구조체

구조체에서는 한가지 독특한 점이 있다. 구조체 않에도 구조체가 나올 수 있다는 점이다.

 이런식으로 다른 구조체를 멤버 변수로 즉 구조체 안에서 구조체를 변수로 설정할 수 있다. 이럴 때,  Student안에 teacher를 사용할 때는 . 연산자를 연속으로 이용해서 참조할 수 있다. 위와 같은 방식을 사용하면, 해당 학생의 담당 선생님 정보를 저장할 수 있다. 

참조연산자 

*연산자는 포인터를 이용할 때 사용한다. 이와 같은 의미를 나타내는 것이 &연산자 주소를 참조하는 연산자이다. 

참조연산자는 포인터의 이름이나 주소 앞에 사용되며, 포인터가 가르키는 변수의 주소를 반환한다. 

먼저 포인터는 주소를 반환하고 포인터 앞에 다시 *을 붙이면 포인터의 주소에 저장되어 있는 데이터를 반환한다. 

포인터에서는 포인터 증감 연산을 사용함에 있어서 조심해야 한다. 

다음의 프로그램을 실행했을 떄 우리가 주목할 부분은 마지막 두 부분이다. 

(*p)++; 의 의미는 p가 가르키는 주소에 있는  num  값을 증가 시키라는 명령이고

*p++;의 의미는 p의 주소, 즉 num의 주소를 증가 시키라는 의미이다. 

자 이제 본격적으로 CPU 스케줄링 시뮬레이터에대해 학습해 보자. 

https://kim-hoya.tistory.com/22

 

CPU 스케줄링 시뮬레이터 C로 만들기

호야의 블로그 [C] 운영체제-CPU 스케줄링 시뮬레이터 만들기 올해 수행했던 운영체제 short term job에서 일어나는 CPU 스케줄러를 구현하고 확인해보겠습니다. C를 이용하였으며 리눅스 환경에서 구현하였습니다..

kim-hoya.tistory.com

이 글에서 제공하는 알고리즘을 활용해서 CPU 스케줄러를 윈도우 환경에서 CLI 방식으로 구현한다. 

#참고로 위의 글의 소스는 들여쓰기 문제와, 실제로 윈도우에서 동작하지 않는 문제, 초기화 문제가 좀 있다....

개요

먼저 이 프로그램을 통해서 우리가 원하는 시뮬레이션 출력 값은 다음과 같다. 

그리고 초기의 프로세스 정보는 proc.txt의 파일 입력을 통해서 불러오도록 구성한다. 

자 가장 먼저 우리가 구현하기 위해서 고민해야 될 부분은 입력과 출력이다. 출력은 위와 같고 

입력은 다음과 같다. 

이런식으로 스페이스를 통해 4가지 정수를 입력 받는다. 각행은 한개의 프로세스를 의미하고

각 열의 값은 Process 번호, Cpu 사용시간(Burst Time), Arrival_time(도착시간), Priority(우선순위)를 의미한다.

우리가 여기서 스케줄링 모니터 프로그램을 구현할 때는 아래 사항을 고려해서 구현한다.

1. BT는 0이 될 수 없다.

2. Priority 알고리즘은 우선순위가 낮은 것이 우선이며, 비선점형 방식이다. 

3. RoundRobin 방식은 메뉴 선택시에 퀀텀을 선택할 수 있도록 한다. 

자 아래는 메뉴 선택창의 출력이다. 

이는 printf문을 활용하고, 진행을 위해서 while로 만든 무한 루프 안에서 

키보드 입력에 따른 case 분기로 진행되고 종료 된다. 각 case 분기에 따라 실행되는 함수가 정해진다.

 

자! 이제 구현해보자

구현하기 위해선 우선 입력과 출력을 정하고, 화면을 어떻게 전시할 것인지를 확인한다. 

그리고 실제로 우리가 원하는 값들을 다루기 위해서 어떤 자료구조를 쓸지,

어떤 함수를 사용해서 값들을 처리할지를 결정해야 한다

구현에 필요한 함수를 가져오기 위해서 아래 3가지 헤더 파일을 inculde 한다.

그리고 매크로문을 통해서, 프로세스 구조체 배열의 최대 크기를 지정해준다.

 

#include  
#include  
#include  
#define MAXSIZE 1000

이제 각 프로세스의 정보를 구조체를 활용해서 담아 보도록 하자. 프로세스 번호와, 동작시간, 도착시간, 우선순위, 대기시간, 전체통작시간, 남은 시간 순으로 변수를 가지며 이를 구조체 안에다 선언해 준다.

typedef struct _process { 
int pro_num, cpu_time, arr_t, pri, wait_t, ta_t, rem_t; 
} 
process;

본 글에서는 다음은 우리가 위에서 언급한 메뉴창을 보고 원하는 동작을 하기 위한 입력을 메인 함수에서 직접처리하는 방식으로 수행한다. 

// 본래 프로그램과의 차이점

 

#정렬을 위해 사용하는 함수이다.

void resort(process *pro, int n);
void at_sort(process *pro, int n);

#스케줄링 알고리즘을 구현한 함수이다. 

int process_fcfs(process *pro, int n);
int process_srt(process *pro, int n);
int process_pri(process *pro, int n);
int process_rr(process *pro, int n, int Q);
int process_sjf(process *pro, int n);
int process_generate(process *pro, int n);

가장 먼저 메임함수를 분석해서 어떻게 동작하는지 알아보자. 

큰 흐름은 다음과 같다.

1.proc.txt. 파일을 읽어온다.

2.ready_queue라는 process 구조체 배열을 선언한다. 

3. 구조체 배열에 파일에서 스페이스를 기준으로  읽은 기준으로 각각 프로세스 번호, Cpu 사용시간, 도착시간, 우선순위를 넣어준다. 

4. 파일이 끝날 때 까지 읽은 값으로 index를 삼아서 여기서 1을 뺀 값으로 현재 파일에 몇개의 프로세스가 있는지 n으로 카운트한다.

5. 파일 입력이 끝나면 키보드로 입력을 받아온 것을 통해서 case문에 따라 각각의 함수를 실행시키고, 그 결과값을 화면에 출력한다. 

6. 메뉴 8번이거나 문자열을 입력할 경우 프로그램을 종료한다.

int main() {

           int i =0;

           int n =0;

           int Q =0;

           int index=0;

           float tat;

           FILE *fp;

           fp=fopen("proc.txt","r");

           process ready_queue[MAXSIZE];

           printf("파일읽기 시작\n");

           while(!feof(fp)) {

                     fscanf(fp, "%d", &ready_queue[i].pro_num);

                     fscanf(fp, "%d", &ready_queue[i].cpu_time);

                     fscanf(fp, "%d", &ready_queue[i].arr_t);

                     fscanf(fp, "%d", &ready_queue[i].pri);

                     ready_queue[i].rem_t=ready_queue[i].cpu_time;

                     index=index+1;

                     printf("%d\n",index);

                     i++;

           }

           fclose(fp);

           printf("파일읽기 끝\n");

           n=index-1;

           printf("%d\n",n);

           printf("\n=================Main Menu====================\n\n1. Read processes from proc.txt\n2. Generate random processes\n3. First come first Serve (FCFS)\n4. Shortest Job First (SJF)\n5. Shortest Remaining time First (SRTF)\n6. Priority\n7. Round Robin (RR)\n8. Exit\n==============================================\n");

           while(1){

                                 int ch = 0;

                                 printf("메뉴를 선택해주세요.\n");

                                 scanf("%d", &ch);         

                                 float tat=0.0;

                                 switch(ch){

                                                                            case 1:

                                  printf("1. Read processes from proc.txt\n====================PROC======================\n");

                                  printf("P#       BT        AT        Pri\n");

                                  for(i=0; i<n; i++) {

                                           printf("%d     %d       %d       %d\n",ready_queue[i].pro_num, ready_queue[i].cpu_time, ready_queue[i].arr_t, ready_queue[i].pri);

                                  }

                                  printf("==============================================\n");

                                  continue;

                                  break;

                             case 2:

                                  printf("2. Generate random processes\n");

                                  process_generate(ready_queue, n);

                                  printf("\n\n==================생성완료===================\n");

                                  n++;

                                  continue;

                                  break;

                             case 3:                 //fcfs

                                  at_sort(ready_queue, n);

                                  process_fcfs(ready_queue, n);

                                  resort(ready_queue, n);

                                  printf("3. First come first Serve (FCFS)\n====================FCFS======================\n");

                                               printf("P#       BT        AT        Pri        WT       TAT\n");

                                               for(i=0; i<n; i++) {

                                           tat=tat+ready_queue[i].ta_t;

                                                               printf("%d          %d       %d       %d       %d       %d\n",ready_queue[i].pro_num, ready_queue[i].cpu_time, ready_queue[i].arr_t, ready_queue[i].pri, ready_queue[i].wait_t, ready_queue[i].ta_t);

                                  }

                                               printf("average turnaround time: %.2f\n",tat/n);

                                               printf("==============================================\n");

                                               continue;

                                               break;

                            case 4:                  //sjf

                                 at_sort(ready_queue, n);

                                 printf("1");

                                 process_sjf(ready_queue, n);

                                 printf("2");

                                                                                       resort(ready_queue, n);

                                                                                      printf("3");

                                 printf("4. Shortest Job First (SJF)\n====================SJF=======================\n");

                                 printf("P#         BT        AT        Pri        WT       TAT\n");

                                 for(i=0; i<n; i++) {

                                          tat=tat+ready_queue[i].ta_t;

                                          printf("%d      %d       %d       %d       %d       %d\n",ready_queue[i].pro_num, ready_queue[i].cpu_time, ready_queue[i].arr_t, ready_queue[i].pri, ready_queue[i].wait_t, ready_queue[i].ta_t);

                                 }

                                 printf("average turnaround time: %.2f\n",tat/n);

                                              printf("==============================================\n");

                                              continue;

                                              break;

                           case 5:                    //srt

                                              at_sort(ready_queue, n);

                                              process_srt(ready_queue, n);

                                              resort(ready_queue, n);

                    

                                              printf("5. Shortest Remaining time First (SRTF)\n====================SRTF======================\n");

                                              printf("P#        BT        AT        Pri        WT       TAT\n");

                                              for(i=0; i<n; i++) {

                                          tat=tat+ready_queue[i].ta_t;

                                          printf("%d      %d       %d       %d       %d       %d\n",ready_queue[i].pro_num, ready_queue[i].cpu_time, ready_queue[i].arr_t, ready_queue[i].pri, ready_queue[i].wait_t, ready_queue[i].ta_t);

                                 }

                                 printf("average turnaround time: %.2f\n",tat/n);

                                              printf("==============================================\n");

                                              continue;

                                              break;

                           case 6:                    //pri

                                at_sort(ready_queue, n);

                                process_pri(ready_queue, n);

                                             resort(ready_queue, n);

                    

                                printf("6. Priority\n====================PRI=======================\n");

                                             printf("P#          BT        AT        Pri        WT       TAT\n");

                                             for(i=0; i<n; i++) {

                                         tat=tat+ready_queue[i].ta_t;

                                         printf("%d        %d       %d       %d       %d       %d\n",ready_queue[i].pro_num, ready_queue[i].cpu_time, ready_queue[i].arr_t, ready_queue[i].pri, ready_queue[i].wait_t, ready_queue[i].ta_t);

                                }

                                             printf("average turnaround time: %.2f\n",tat/n);

                                             printf("==============================================\n");

                                             continue;

                                             break;

                            case 7:                  //RR

                                 printf("퀀텀 입력\n");

                                 scanf("%d",&Q);

                                 at_sort(ready_queue, n);

                                 process_rr(ready_queue, n, Q);

                                 resort(ready_queue, n);

                                 printf("7. Round Robin (RR)\n====================RR========================\n");

                                 printf("P#         BT        AT        Pri        WT       TAT\n");

                                 for(i=0; i<n; i++) {

                                          tat=tat+ready_queue[i].ta_t;

                                          printf("%d      %d       %d       %d       %d       %d\n",ready_queue[i].pro_num, ready_queue[i].cpu_time, ready_queue[i].arr_t, ready_queue[i].pri, ready_queue[i].wait_t, ready_queue[i].ta_t);

                                 }

                                 printf("average turnaround time: %.2f\n",tat/n);

                                 printf("==============================================\n\n");

                                 ent_key=0;

                                 continue;

                                 break;

                            case 8:

                                              printf("\n\n====================EXIT======================\n");

                                              exit(0);

                                              break;

                                 }

                           }

  }      

자 먼저 정렬을 위해 사용하는 함수들 부터 다루어 보자. 

1. void at_sort()는 도착한 시간 순으로 프로세스를 정렬하는 함수이다. FCFS스케줄링을 수행할 때, 먼저 도착한 시간 순으로 정렬해 놓고 알고리즘을 적용시키기 위함이다. 단계적 문제해결 이라고 생각하면 될 것 같다. 

2. void resort()는 도착시간 순으로 정렬된 프로세스를 다시 원래 프로세스 번호 순으로 재정렬 한다. 

자 이제 스케줄링 함수들을 다루어 보자. 

1.int process_fcfs()는 먼저 도착한 프로세스를 먼저 실행시크는 알고리즘이다. 

2. int process_srt() 남은 시간이 적은 것 먼저 수행시키는 값이다. 이는 실제로는 어렵다. 프로그램이 언제 종료 되는지 결정할 수 없기 때문이다. Halting-problem

3.int process_pri()는 우선순위를 보고 높은 우선순위인 프로세스 먼저 실행한다. 이때, 낮은 값이 높은 우선순위를 가진다.

4. int process_sjf()는 동작시간이 짧은 프로세스를 우선처리 한다. 이부분도 마찬가지다. 실제로는 결정할 수 없다. 언제 끝날지 모르기 때문이다. 

5.int process_rr() 는 라운드 로빈 방식이다 타임퀀텀만큼 들어온 순서대로 수행하고 다음으로 넘어가는 알고리즘이다. 이는 FCFS에서 퀀텀만 추가되었다.

6.int process_generate() 우리가 텍스트 파일에서 입력 받은 거 이외에도 무작위로 프로세스를 생성하기 위해 사용하는 함수이다. 프로세스가 증가할 때, 각각의 스케줄링 방식에 따른 차이를 비교할 수 있다. 

 

전체 프로그램

#include <stdio.h>

#include <stdlib.h>

#include <windows.h>

#define MAXSIZE 1000

//------사용할 자료 구조 선언--------------------------------------

typedef struct _process {

           int pro_num, cpu_time, arr_t, pri, wait_t, ta_t, rem_t;

}

process;

           // 프로세스 식별번호

           // 프로세스가 CPU를 사용한 시간

           // 프로세스 우선순위

           //프로세스 대기시간

           //프로세스 전체 시간 , WT+BT

           //남은 동작 시간

 

//------------스케줄링 알고리즘 함수--------------------------------

int process_fcfs(process *pro, int n);

int process_srt(process *pro, int n);

int process_pri(process *pro, int n);

int process_rr(processs *pro, int n, int Q);

// 라운드 로빈은 타임 퀀텀도 같이 매개변수로 받는다.

int process_sjf(process *pro, int n);

int process_generate(process *pro, int n);

// -----------프로세스를 정렬 함수 ---------------------------------

void at_sort(process *pro, int n);

void resort(process *pro, int n);

 

 

//===========================================================================================

int main() {

           int i =0;

           int n =0;

           int Q =0;

           int index=0;

           float tat;

           FILE *fp;

           fp=fopen("proc.txt","r");

           process ready_queue[MAXSIZE];

           printf("파일읽기 시작\n");

           while(!feof(fp)) {

                     fscanf(fp, "%d", &ready_queue[i].pro_num);

                     fscanf(fp, "%d", &ready_queue[i].cpu_time);

                     fscanf(fp, "%d", &ready_queue[i].arr_t);

                     fscanf(fp, "%d", &ready_queue[i].pri);

                     ready_queue[i].rem_t=ready_queue[i].cpu_time;

                     index=index+1;

                     printf("%d\n",index);

                     i++;

           }

           fclose(fp);

           printf("파일읽기 끝\n");

           n=index-1;

           printf("%d\n",n);

           printf("\n=================Main Menu====================\n\n1. Read processes from proc.txt\n2. Generate random processes\n3. First come first Serve (FCFS)\n4. Shortest Job First (SJF)\n5. Shortest Remaining time First (SRTF)\n6. Priority\n7. Round Robin (RR)\n8. Exit\n==============================================\n");

           while(1){

                                 int ch = 0;

                                 printf("메뉴를 선택해주세요.\n");

                                 scanf("%d", &ch);         

                                 float tat=0.0;

                                 switch(ch){

                                                                            case 1:

                                  printf("1. Read processes from proc.txt\n====================PROC======================\n");

                                  printf("P#       BT        AT        Pri\n");

                                  for(i=0; i<n; i++) {

                                           printf("%d     %d       %d       %d\n",ready_queue[i].pro_num, ready_queue[i].cpu_time, ready_queue[i].arr_t, ready_queue[i].pri);

                                  }

                                  printf("==============================================\n");

                                  continue;

                                  break;

                             case 2:

                                  printf("2. Generate random processes\n");

                                  process_generate(ready_queue, n);

                                  printf("\n\n==================생성완료===================\n");

                                  n++;

                                  continue;

                                  break;

                             case 3:                 //fcfs

                                  at_sort(ready_queue, n);

                                  process_fcfs(ready_queue, n);

                                  resort(ready_queue, n);

                                  printf("3. First come first Serve (FCFS)\n====================FCFS======================\n");

                                               printf("P#       BT        AT        Pri        WT       TAT\n");

                                               for(i=0; i<n; i++) {

                                           tat=tat+ready_queue[i].ta_t;

                                                               printf("%d          %d       %d       %d       %d       %d\n",ready_queue[i].pro_num, ready_queue[i].cpu_time, ready_queue[i].arr_t, ready_queue[i].pri, ready_queue[i].wait_t, ready_queue[i].ta_t);

                                  }

                                               printf("average turnaround time: %.2f\n",tat/n);

                                               printf("==============================================\n");

                                               continue;

                                               break;

                            case 4:                  //sjf

                                 at_sort(ready_queue, n);

                                 printf("1");

                                 process_sjf(ready_queue, n);

                                 printf("2");

                                                                                      resort(ready_queue, n);

                                                                                      printf("3");

                                 printf("4. Shortest Job First (SJF)\n====================SJF=======================\n");

                                 printf("P#         BT        AT        Pri        WT       TAT\n");

                                 for(i=0; i<n; i++) {

                                          tat=tat+ready_queue[i].ta_t;

                                          printf("%d      %d       %d       %d       %d       %d\n",ready_queue[i].pro_num, ready_queue[i].cpu_time, ready_queue[i].arr_t, ready_queue[i].pri, ready_queue[i].wait_t, ready_queue[i].ta_t);

                                 }

                                 printf("average turnaround time: %.2f\n",tat/n);

                                              printf("==============================================\n");

                                              continue;

                                              break;

                           case 5:                    //srt

                                              at_sort(ready_queue, n);

                                              process_srt(ready_queue, n);

                                              resort(ready_queue, n);

                    

                                              printf("5. Shortest Remaining time First (SRTF)\n====================SRTF======================\n");

                                              printf("P#        BT        AT        Pri        WT       TAT\n");

                                              for(i=0; i<n; i++) {

                                          tat=tat+ready_queue[i].ta_t;

                                          printf("%d      %d       %d       %d       %d       %d\n",ready_queue[i].pro_num, ready_queue[i].cpu_time, ready_queue[i].arr_t, ready_queue[i].pri, ready_queue[i].wait_t, ready_queue[i].ta_t);

                                 }

                                 printf("average turnaround time: %.2f\n",tat/n);

                                              printf("==============================================\n");

                                              continue;

                                              break;

                           case 6:                    //pri

                                at_sort(ready_queue, n);

                                process_pri(ready_queue, n);

                                             resort(ready_queue, n);

                    

                                printf("6. Priority\n====================PRI=======================\n");

                                             printf("P#          BT        AT        Pri        WT       TAT\n");

                                             for(i=0; i<n; i++) {

                                         tat=tat+ready_queue[i].ta_t;

                                         printf("%d        %d       %d       %d       %d       %d\n",ready_queue[i].pro_num, ready_queue[i].cpu_time, ready_queue[i].arr_t, ready_queue[i].pri, ready_queue[i].wait_t, ready_queue[i].ta_t);

                                }

                                             printf("average turnaround time: %.2f\n",tat/n);

                                             printf("==============================================\n");

                                             continue;

                                             break;

                            case 7:                  //RR

                                 printf("퀀텀 입력\n");

                                 scanf("%d",&Q);

                                 at_sort(ready_queue, n);

                                 process_rr(ready_queue, n, Q);

                                 resort(ready_queue, n);

                                 printf("7. Round Robin (RR)\n====================RR========================\n");

                                 printf("P#         BT        AT        Pri        WT       TAT\n");

                                 for(i=0; i<n; i++) {

                                          tat=tat+ready_queue[i].ta_t;

                                          printf("%d      %d       %d       %d       %d       %d\n",ready_queue[i].pro_num, ready_queue[i].cpu_time, ready_queue[i].arr_t, ready_queue[i].pri, ready_queue[i].wait_t, ready_queue[i].ta_t);

                                 }

                                 printf("average turnaround time: %.2f\n",tat/n);

                                 printf("==============================================\n\n");

                                 ent_key=0;

                                 continue;

                                 break;

                            case 8:

                                              printf("\n\n====================EXIT======================\n");

                                              exit(0);

                                              break;

                                 }

                           }

  }      

          

          

          

void at_sort(process *pro, int n) {

// arival time 순으로 프로세스를 정렬 시켜 준다. 

           process temp;

           int i,j;

           for (i=n-1; i>0;i--) {

                     for (j=0;j<i;j++) {

                                // i n-1부터 시작해서 0 부터 n 까지 process를 비교하고, 그다음  i n-2 가 되면 맨 앞에껄 두고 그 다음 부터 마지막까지 비교 한다. 

                                if(pro[j].arr_t>pro[j+1].arr_t) {

                                           temp=pro[j+1];

                                           pro[j+1]=pro[j];

                                           pro[j]=temp;

                                } else if(pro[j].arr_t==pro[j+1].arr_t&&pro[j].pro_num>pro[j+1].pro_num) {

                                           //동시에 왔으면 프로세스 번호 순으로 정렬한다. 작은 번호가 먼저 나온다. 

                                           temp=pro[j+1];

                                           pro[j+1]=pro[j];

                                           pro[j]=temp;

                                }

                     }

           }

}

 

void resort(process *pro, int n) {

//프로세스 구조체

// i n-1부터 시작해서 0 부터 n 까지 process를 비교하고, 그다음  i n-2 가 되면 맨 앞에껄 두고 그 다음 부터 마지막까지 비교 한다. 

//도착한 순서대로 정렬된 프로세스 구조체를 가져와서 CPU_time과 대기시간 WT를 더해 준다.

           process temp;

           int i,j;

           for (i=n-1; i>0;i--) {

                     for (j=0;j<i;j++) {

                                if(pro[j].pro_num>pro[j+1].pro_num) {

                                           temp=pro[j+1];

                                           pro[j+1]=pro[j];

                                           pro[j]=temp;

                                }

                     }

           }

}

 

int process_fcfs(process *pro, int n) {

//i 0부터,1, 2, 3, 4, 5, n-1 까지

// j i값에 따라서(i,j)로 표현 하면

// (0,0) (1,0) (2,(0,1)), (3,(0,1,2)),

//...(n-1, (0,1,2,3,..,n-2))이런식으로

//process cpu_time temp에 누적한다.

//만약 첫번째 것만 도착했으면, 첫번째 프로세스의 cpu_time

//그 뒤로 

// 대기시간은 = 전체 CPU 사용 시간에서, k가 먼저 왔으니까,

// i가 도착한 시간을 뺴고, 거기에 k의 도착시간을 더하면, 기다린 시간이다.

// 대기 시간이 없는 경우 바로 수행하기 때문에

// 남은 동작 시간을 매시간 계산하여 가장 짧은 남은 동작을 가진 프로세스 먼저 하며,

//선점 형으로 동 작

           int temp;

           int wt=0;

           int i,j,k=0;

           for (i=0;i<n;i++) {

                     temp=0;

                     for (j=k;j<i;j++) {

                                temp=temp+pro[j].cpu_time;

                     }

                     wt=temp-pro[i].arr_t+pro[k].arr_t;

                     if(wt<=0) {

                                k=i;

                                pro[i].wait_t=0;

                                pro[i].ta_t=pro[i].cpu_time + pro[i].wait_t;

                     } else {

                                pro[i].wait_t=wt;

                                pro[i].ta_t=pro[i].cpu_time + pro[i].wait_t;

                     }

           }

}

int process_srt(process *pro, int n) {

//남은 프로세스 수

// 현재 시간

// for문에서 선택 되는 현재 process의 도착 시간이 now같거나 작고

// i n보다 작을 때 까찌, 증감시키면서

//해당 프로세스의 남은 시간이 최소값 보다 작고, 양수이면

// 지금 실행할 프로세스를 i로 잡는다. 

//그리고 현재 프로세스의 남은 시간을 최소 값으로 잡니다.

// 반복문을 돌면서 이 값은 최소값이 된다. 

// 남은 시간값이 현재 now_p보다 작지 않을 때, 

//시간을 증가시킨다.

//temp[0]의 값이 process[0] cpu_time 시간과 다 때, 

// temp에다가 n개 만큼의 남은 시간을 채워 넣는다. 

// 시간이 지날 수록 현재 사용하고 있는 프로세스의

// 남은 동작 시간 카운트를 감소 시킨다. 

// 남은 동작시간이 0일 때 새로운 프로세스를 재선택 하는 과정

// 남은 프로세스를 감소시켜준다. 

// 스케줄링 완료한 값이 temp에 각각의 index에 담겨 있었는데 이를 다시

//process remain_t에다 저장해 준다. 

// 우선순위대로 스케쥴링 작을 수록 우선순위 높은거

           int remain, min, now_p, i, temp[150];

           int now, wt=0;

           remain=n;

           now=pro[0].arr_t;

           while(remain>0) {

                     min=5000;

                     for (i=0; pro[i].arr_t<=now && i<n; i++) {

                                if(pro[i].rem_t<min && pro[i].rem_t>0) {

                                           now_p=i;

                                           min=pro[i].rem_t;

                                }

                     }

                     now++;

                     if(temp[0] !=pro[0].cpu_time) {

                                for (i=0; i<n; i++) {

                                           temp[i]=pro[i].rem_t;

                                }

                     }

                     pro[now_p].rem_t--;

                     if(pro[now_p].rem_t==0) {

                                pro[now_p].wait_t=now-pro[now_p].arr_t-pro[now_p].cpu_time;

                                pro[now_p].ta_t=pro[now_p].cpu_time + pro[now_p].wait_t;

                                wt=wt+pro[now_p].wait_t;

                                remain--;

                     }

           }

           for (i=0; i<n; i++) {

                     pro[i].rem_t=temp[i];

           }

}

int process_pri(process *pro, int n) {

// 우선 남은 시간을 다 해당 process cpu_time으로 채워준다.

//현재 시간을 process[0]이 도착한 시간으로 잡는다. 

//남은 프로세스 의 수

// temp에다 process들의 남은 시간을 채워준다.

// 새로 들어오는 애들로 부터

//끝난 프로세스가 아닌데 현재 min보다 우선순위값이 작은 프로세스면

//그 프로세스 번호가 num이 되고 

// 그 프로세스의 우선순위가 최소 값이 되며

//flag 1로 바꿔준다.

//시간을 증가 시킨다. 

//pro[num]을 다 수행하고 시간에다가 추가해주는 것이다.

           int flag = 0;

           int i,time,remain,num, min, temp[150];

           for (i=0; i<n; i++) {

                     pro[i].rem_t = pro[i].cpu_time;

           }

           time = pro[0].arr_t;

           remain = n;

           if(temp[0] !=pro[0].cpu_time) {

                     for (i=0; i<n; i++) {

                                temp[i]=pro[i].rem_t;

                     }

           }

           while(remain>0) {

                     min = 9999;

                     for (i=0; pro[i].arr_t <= time && i<n; i++) {

                                if(pro[i].rem_t != 0 && pro[i].pri<min && pro[i].cpu_time>0) {

                                           num = i;

                                           min = pro[i].pri;

                                           flag = 1;

                                }

                     }

                     if(flag ==1) {

                                pro[num].rem_t = 0;

                                pro[num].wait_t = time - pro[num].arr_t;

                                remain--;

                                time += pro[num].cpu_time;

                     } else {

                                time ++;

                     }

                     flag = 0;

           }

           for (i=0; i<n; i++) {

                     pro[i].ta_t = pro[i].wait_t + pro[i].cpu_time;

           }

           for (i=0; i<n; i++) {

                     pro[i].rem_t=temp[i];

           }

}

int process_sjf(process *pro, int n) {

           int flag = 0;

           int i,time,remain,num, min, temp[150];

           for (i=0; i<n; i++) {

                     pro[i].rem_t = pro[i].cpu_time;

           }

           time = pro[0].arr_t;

           remain = n;

           if(temp[0] !=pro[0].cpu_time) {

                     for (i=0; i<n; i++) {

                                temp[i]=pro[i].rem_t;

                     }

           }

           while(remain>0) {

                     min = 9999;

                     for (i=0; pro[i].arr_t <= time && i<n; i++) {

                                if(pro[i].rem_t != 0 && pro[i].cpu_time<min && pro[i].cpu_time>0) {

                                           num = i;

                                           min = pro[i].cpu_time;

                                           flag = 1;

                                }

                     }

                     if(flag ==1) {

                                pro[num].rem_t = 0;

                                pro[num].wait_t = time - pro[num].arr_t;

                                remain--;

                                time += pro[num].cpu_time;

                     } else {

                                time ++;

                     }

                     flag = 0;

           }

           for (i=0; i<n; i++) {

                     pro[i].ta_t = pro[i].wait_t + pro[i].cpu_time;

           }

           for (i=0; i<n; i++) {

                     pro[i].rem_t=temp[i];

           }

}

int process_rr(process *pro, int n, int Q) {

// temp에다 값저장 temp2에다는 process들의 특정 값 저장

//int i , count 그리고 totaltime

//초기화 절차

// process들의 남은 시간을 temp2 배열에 넣어준다.

//무한 루프

// 현재 임시 값은 quantom

// 만약 process i의 남은 시간이 없다면, 

// count를 증가 시키고, 

//i를 증가 시켜 다른 process로 간다. 

// 만약 남은 시간이 퀀텀보다 크다면, 그 값을 빼준다음 다시 저장

// 남은시간이 0이거나 퀀텀보다 크다면,

// temp에다가 남은 시간 저장해주고,

// 실행했으니까, pro[i].remain_t 0으로

// 전체 시간은 수행한 시간, 왜냐하면 위에서

//퀀텀보다 작을 때, 그 값을 total time에 넣어 주었다.

//process[i]의 전체 시간은 tt

// 다 돌았을 때,

//while문 여기 까지

// 이제 그동안 temp에 모았던거 reamin_t로 넣어준다.

// wait 시간은 전체 시간 - cpu시간

           int temp, temp2[150];

           int i, count;

           int tt =0;

           //tt에 쓰레기 값이 들어가면 않된다.

           if(temp2[0] !=pro[0].cpu_time) {

                     for (i=0; i<n; i++) {

                                temp2[i]=pro[i].rem_t;

                     }

           }

           while(1) {

                     for (i=0,count=0;i<n;i++) {

                                temp=Q;

                                if(pro[i].rem_t==0) {

                                           count++;

                                           continue;

                                }

                                if(pro[i].rem_t>Q)

                                                                           pro[i].rem_t=pro[i].rem_t-Q; else if(pro[i].rem_t>=0) {

                                           temp=pro[i].rem_t;

                                           pro[i].rem_t=0;

                                }

                                tt=tt+temp;

                                pro[i].ta_t=tt;

                     }

                     if(n==count)

                                                     break;

           }

           for (i=0;i<n;i++) {

                     pro[i].rem_t=temp2[i];

                     pro[i].wait_t=pro[i].ta_t-pro[i].cpu_time;

           }

}

int process_generate(process *pro, int n) {

           // 랜덤 프로세스 생성, 

           FILE *fp2;

           int j, found;

           fp2=fopen("proc.txt","a+");

           int i=n;

           //프로세스 개수, 현재 마지막 프로세스가 몇개인지 파악하는 데 사용된다.

           int bt =(rand()%25)+1;

           pro[i].pro_num=i+1;

           pro[i].cpu_time=bt;

           while(1) {

                     pro[i].pri=rand()%50;

                     found=0;

                     for (j=0;j<i;++j) {

                                if(pro[j].pri==pro[i].pri) {

                                           found=1;

                                           break;

                                }

                     }

                     if(!found) break;

           }

           while(1) {

                     pro[i].arr_t=rand()%50;

                     found=0;

                     for (j=0;j<i;++j) {

                                if(pro[j].arr_t==pro[i].arr_t) {

                                           found=1;

                                           break;

                                }

                     }

                     if(!found) break;

           }

           fprintf(fp2,"\r\n%d %d %d %d",pro[i].pro_num, pro[i].cpu_time, pro[i].arr_t, pro[i].pri);

           fclose(fp2);

}

깃허브에 올리겠습니다. 잠시만 기다려주세요.

'▶ 알고리즘' 카테고리의 다른 글

c++ 지뢰찾기  (0) 2020.04.11
c++ 딕셔너리 만들기  (0) 2020.04.11
C++ 원소의 우선순위 결정하기  (0) 2020.04.11
알고리즘  (0) 2018.12.10
알고리즘- 정보과학의 문제  (0) 2018.08.08