[과제] 운영체제_메모리할당방식_연속메모리할당_최초,최악적합 구현하기

728x90

[코드 설명]

<프로세스 구조체>

-프로세스 내부 데이터인 프로세스 idsize를 구조체로 묶어주었다.

typedef struct Process { 
	int pid; 
	int size; //size(10~100)
}Process;

<메모리 구조체>

-메모리의 내부 데이터를 프로세스 타입 배열 / 각 프로세스가 사용중인지 여부 표시용 Using배열/ 주소로 두고 구조체로 묶어주었다.

typedef struct Memory { 
	Process process[30];
	int Using[30]; //각 프로세스 사용중 여부 
	int address = 0;
}Memory;

<초기 메모리 생성연산>

-초기 메모리 상태는 프로세스 5개가 메모리 위에 올라가 있어야 한다.

따라서, for루프를 돌면서 카운터 5이하 프로세스에 한해서 using[]배열에 TRUE값을 주어 메모리 사용처리를 해준 뒤, 각 프로세스의 사이즈를 랜덤함수 (10~100) 사잇값 난수 생성하여 size 처리해두었다.  

-또한, 메모리의 5개의 프로세스를 제외한 공간에서 Using[] 배열값은 FALSE값으로 초기화해주어야 하므로, 아래와 같이 연산을 해두었다.

void createMemory(Memory* m) {//초기 공백 메모리 상태
	int i; 
	for (int i = 1; i < 30; i++) {
		if (i <= 5) {
			m->Using[i] = TRUE;
			m->process[i].size = (rand() % 100) + 10;
		}
		if (6 <= i) {
			m->Using[i] = FALSE;
			m->process[i].size = m->process[i].size = (rand() % 100) + 10;
		}
	}

}

<<프로세스 생성>>

-프로세스 생성 시, 메모리 위에 최초적합을 할지, 최악적합을 할지 사용자에게 입력받은 뒤,

최초적합 연산과 최악적합 연산 각각을 따로 함수화하였다.

                                                                                                                                                

<최초적합 삽입 연산>

-최초적합으로 메모리를 할당해줄 경우, 운영체제는 사용중이지 않은 공간() 중에서 첫 번째로 사용 가능한 가용 공간을 할당해주어야 한다.

-따라서, Using[]배열을 for루프로 차례로 돌면서 배열값이 FALSE인 공간을 탐색하는데,

(최초적합) 할당 공간은, 처음 만난 빈(FALSE) 공간이면서도 생성된 프로세스 size값보다 큰 공간이어야 하기 때문에 if문으로 적합한 위치 i를 찾았다면, 해당 위치의 Using[i] (메모리 사용여부) TRUE로 업데이트 시켜주고, 사용자에게 받은 pid size값을 업데이트 시켜준다. 더불어 address값또한 생성된 프로세스 size만큼 ++처리해준다.

void insertFirstProcess(Memory* m, Process *p) { //프로세스 삽입(최초적합)

	if ((m->address) > MAX_SIZE) { //메모리 주소가 1000 넘어가면 오버플로우
		printf("메모리 오버플로우\n");
		return;
	}

	for (int i = 0; i < 30; i++) { //Using[] 내부 차례로 돌면서 
		
		if((m->Using[i] == FALSE) && (m->process[i].size > p->size)) { 
//처음 발견한 빈 공간 (최초적합)

			m->Using[i] = TRUE; //현재 공간 사용중 업데이트 
			m->process[i].pid = p->pid;
			m->process[i].size = p->size;
			m->address += p->size; //주소 ++ 처리
			
			break;
		}
	}
}

 

<최악적합 삽입 연산>

-최악적합 할당 방식은, 메모리 위의 빈 공간 중 가장 max값의 가용 공간을 택하여 프로세스를 할당해주어야 한다.

-따라서, 최악적합 삽입 연산에서는 for루프로 Using[]배열 내부를 돌되, size max값인 공간을 찾아야 하기 때문에, 비어있는(Using[] == FALSE) 공간 중에서 현재의 max값보다 큰 size의 가용공간을 발견할 경우, 해당 i값을 insert변수에 저장시켜준 뒤, max값을 업데이트시켜준다.

-for루프를 빠져나온 insert값은 가장 max값인 가용공간 위치를 저장하고 있을 것이므로 해당 위치에 대한 Using[i] (메모리 사용여부)TRUE로 업데이트 시켜주고, 사용자에게 받은 pid size값을 업데이트 시켜준다. 더불어 address값또한 생성된 프로세스 size만큼 ++처리해준다.

void insertWorstProcess(Memory* m, Process* p) { //프로세스 삽입 (최악적합)
	
	int insert; //삽입위치저장용
	if ((m->address) > MAX_SIZE) {//메모리 주소가 1000 넘어가면 오버플로우
		printf("메모리 오버플로우\n");
		return;
	}

	int max = m->process[0].size; //max 사이즈 갖는 공간찾을 용도
	for (int i = 0; i < 30; i++) { 
		if ((m->Using[i] == FALSE)) { //Using[] 돌면서 비어있는 공간 중
			if (max < m->process[i].size) { //현 max보다 큰 공간 발견시
				max = m->process[i].size;
				insert = i; //max값 갖는 i 저장시킴 
			}
		}
	}

	//for 빠져나온 insert는 현재 size max값 갖는 공간
	m->Using[insert] = TRUE; //max 메모리 공간 사용처리 
	m->process[insert].pid = p->pid;
	m->process[insert].size = p->size;

	m->address += p->size; //주소 ++ 처리
}

<<프로세스 삭제 연산>>

-프로세스 삭제 시, 사용자로부터 받은 pid값을 이용해, for루프를 돌면서 해당 pid값을 갖는 프로세스를 찾은 후, 찾은 위치 i에 대하여 Using[]값을 FALSE로 업데이트시켜준다. 또한 삭제되어 반환된 프로세스의 size = 0 값으로, address값도 size만큼 처리하여 준다.

void deleteProcess(Memory*m, int pid) { //프로세스 삭제

	for (int i = 0; i < 30; i++) {
		if (m->process[i].pid == pid) {
			m->Using[i] = FALSE;
			m->address -= m->process[i].size; //주소 --처리
			m->process[i].size = 0;
		}
	}
}

<빈 메모리 목록 출력 연산>

-빈 메모리 목록을 보여주기 위해서는 비어있는 Hole 공간을 관리해주어야 한다.

만약 for루프를 돌면서 Using[]배열값이 연달아 FALSE (연달아 빈공간)을 만나게 될 경우,

중복을 방지하기 위해서 size값은 합쳐준 뒤, 다시, for루프를 돌면서 Using[] FALSE인 빈 공간 size를 차례로 출력시켜주었다.

void printMemory(Memory* m) { //빈 메모리 목록

	for (int i = 0; i < 30; i++) { //홀 관리 
		if ((m->Using[i] == FALSE) && (m->Using[i + 1] == FALSE)) {
 //연달아 빈공간인 경우 합침				
			m->process[i].size += m->process[i + 1].size; //size 합쳐주고 
			m->process[i + 1].size = 0;
		}
	}
	printf("비어있는 메모리 공간 Hole 목록\n");
	for (int i = 0; i < 30; i++) {
		if ((m->Using[i] == FALSE) && (m->process[i].size != 0)) {
				printf("[Hole] size : %d", m->process[i].size);
		}
	}
}

<실행 메인 main() 함수>

1) for루프를 30번 돌면서 사용자에게 프로세스의 생성 or 삭제 의사를 물어본 뒤,

-만약 프로세스 생성한다면, 생성할 프로세스의 id, size값을 받고,  

(최초적합, 최악적합) 중 어떤 할당방식으로 할당할지 고르게 하여 해당 연산함수를 호출시켜준다.

-만약 프로세스 삭제한다면, 삭제할 프로세스의 id값을 받은 뒤, 삭제연산함수를 호출시켜준다.

-각 연산을 마친 뒤, 메모리 상태를 보여주기 위해 빈 공간을 보여준다.

 

2) for루프를 빠져나온 뒤, 최종 메모리 상태를 for문을 돌면서 보여준다.

Using[]배열값이 TRUE인 경우, -> 메모리 위에 적재된 프로세스 상태를

Using[]배열값이 FALSE인 경우 -> 메모리 위의 빈 공간 상태를 보여주도록 만들어주었다.

int main() {
	int o;
	int id;
	int Psize;
	Process p;

	Memory* m = (Memory*)malloc(sizeof(Memory));
	createMemory(m);


	for (int i = 0; i < 30; i++) { //30번 루프 돌면서 
		printf("\n ----------------------------------------------- \n");
		printf("프로세스 생성  = 1 or 삭제  = 2 \n");
		scanf_s("%d", &o);
		if (o == 1) { //프로세스 생성 
			printf("생성할 프로세스 id번호\n");
			scanf_s("%d", &id);
			printf("생성할 프로세스 크기 (10~100)\n");
			scanf_s("%d", &Psize);

			Process p;
			p.pid = id;
			p.size = Psize;

			printf("최초적합 = 1, 최악적합 = 2  \n");
			scanf_s("%d", &o);

			if(o == 1) { //최초적합 
				insertFirstProcess(m, &p);
				printMemory(m);
			}
			else if(o == 2) {//최악적합 
				insertWorstProcess(m, &p);
				printMemory(m);
			}
			else {
				printf("잘못 입력하셨습니다.");
			}
		}

		else if (o == 2) { //프로세스 삭제 
			printf("삭제할 프로세스 pid 번호\n");
			scanf_s("%d", &id);

			deleteProcess(m, id);
			printMemory(m);
		}

		else {
			printf("잘못 입력하셨습니다. 다시 입력하세요\n ");
		}

	}
	printf("\n ----------------------------------------------- \n");
	printf("\n\n 최종 사용 중인 프로세스 목록 : \n");
	for (int i = 0; i < 30; i++) {
		if (m->Using[i] == TRUE) {
			printf("[P %d] size : %d, address : %d \n", i, m->process[i].size, m->address);
		}
	}
	printf("\n ----------------------------------------------- \n");
	printf("최종");
	printMemory(m);



	getchar();
	getchar();

	return 0;
}

[실행결과화면]

728x90