[코드 설명]
<프로세스 구조체>
-프로세스 내부 데이터인 프로세스 id와 size를 구조체로 묶어주었다.
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;
}
[실행결과화면]
'[CS] 전공 공부 모음 > [학교] OS_운영체제' 카테고리의 다른 글
[과제] 운영체제_프로세스 우선순위 큐_C언어, 최대힙 이용해서 구현하기 (0) | 2021.12.12 |
---|