Q1.
Deadlock이 발생하는 다음의 벡터 덧셈 코드를 Deadlock이 발생하는 네 가지 조건 관 점으로 각각 분석하시오. (28점 - 각 조건 당 7점)
void vector_add (vector_t *v_dst, vector_t *v_src)
{
int i; Pthread_mutex_lock (&v_dst->lock);
Pthread_mutex_lock (&v_src->lock);
for (i=0; i < VECTOR_SIZE; i++)
{
v_dst->values[i] = v_dst->values[i] + v_src->values
}
Pthread_mutex_unlock (&v_dst->lock);
Pthread_mutex_unlock (&v_src->lock);
}
A1.
주어진 벡터 덧셈 코드에서 데드락이 발생할 수 있는 네 가지 조건을 각각 분석해보겠습니다:
void vector_add(vector_t *v_dst, vector_t *v_src) {
int i;
Pthread_mutex_lock(&v_dst->lock);
Pthread_mutex_lock(&v_src->lock);
for (i = 0; i < VECTOR_SIZE; i++) {
v_dst->values[i] = v_dst->values[i] + v_src->values[i];
}
Pthread_mutex_unlock(&v_dst->lock);
Pthread_mutex_unlock(&v_src->lock);
}
### 1. 상호 배제 (Mutual Exclusion)
**조건 설명**:
상호 배제는 하나의 자원(여기서는 벡터)에 대해 동시에 여러 스레드가 접근할 수 없음을 의미합니다.
**코드 분석**:
이 코드에서 `Pthread_mutex_lock` 함수로 벡터의 락을 거는 부분이 상호 배제 조건을 충족시킵니다. `v_dst`와 `v_src` 벡터에 대해 각각의 락이 걸려 있으므로, 한 스레드가 락을 걸고 있는 동안 다른 스레드는 해당 벡터에 접근할 수 없습니다.
Pthread_mutex_lock(&v_dst->lock);
Pthread_mutex_lock(&v_src->lock);
### 2. 점유와 대기 (Hold and Wait)
**조건 설명**:
점유와 대기는 하나의 자원을 점유하고 있으면서 동시에 다른 자원을 기다리는 상황을 말합니다.
**코드 분석**:
이 코드에서는 한 스레드가 `v_dst`에 대한 락을 건 상태에서 `v_src`에 대한 락을 기다립니다. 이로 인해 점유와 대기 조건이 충족됩니다.
Pthread_mutex_lock(&v_dst->lock); // v_dst 락을 점유
Pthread_mutex_lock(&v_src->lock); // v_src 락을 기다림
### 3. 비선점 (No Preemption)
**조건 설명**:
비선점은 자원이 강제로 회수되지 않음을 의미합니다. 자원을 점유한 스레드가 자원을 스스로 해제할 때까지 기다려야 합니다.
**코드 분석**:
이 코드에서는 한 번 락을 걸면, 해당 락은 스레드가 명시적으로 `Pthread_mutex_unlock`을 호출할 때까지 유지됩니다. 따라서 자원을 강제로 빼앗을 수 없기 때문에 비선점 조건이 충족됩니다.
Pthread_mutex_unlock(&v_dst->lock);
Pthread_mutex_unlock(&v_src->lock);
### 4. 순환 대기 (Circular Wait)
**조건 설명**:
순환 대기는 자원 대기 관계가 순환 구조를 이루는 상황을 말합니다.
**코드 분석**:
두 스레드 `T1`과 `T2`를 고려해보면:
- `T1`은 `v_dst`에 대한 락을 걸고 `v_src`에 대한 락을 기다립니다.
- `T2`는 `v_src`에 대한 락을 걸고 `v_dst`에 대한 락을 기다립니다.
이 경우, `T1`과 `T2`는 서로의 락을 기다리면서 순환 대기 상태에 빠질 수 있습니다.
T1: v_dst를 점유 -> v_src를 기다림
T2: v_src를 점유 -> v_dst를 기다림
이로 인해 순환 대기 조건이 충족됩니다.
### 요약
결론적으로, 주어진 코드는 다음의 네 가지 데드락 조건을 모두 충족시킵니다:
1. **상호 배제**: 벡터에 대한 락이 걸려 있는 동안 다른 스레드는 접근할 수 없음.
2. **점유와 대기**: 한 스레드가 하나의 락을 점유하고 다른 락을 기다림.
3. **비선점**: 한 번 걸린 락은 강제로 해제되지 않음.
4. **순환 대기**: 스레드 간에 자원 대기 관계가 순환을 이룸.
따라서 이 코드는 특정 조건에서 데드락을 유발할 수 있습니다.
Q2.
다음 코드와 같이 /foo/bar 파일을 읽는 과정에서 발생하는 동작과 발생하지 않는 동작을 아래 표에 Yes 또는 No로 구분하시오.
• 하나의 블록은 4KB 크기를 갖는다고 가정
• Page cache 등의 캐쉬와 버퍼링은 없다고 가정
• inode는 두 개의 direct pointer 하나의 indirect pointer를 갖고 있다고 가정
my_fd = open("/foo/bar", O_RDONLY);
for ( i = 0; i < 2; i++ )
read (my_fd, buf, 4096);
2.1 두 번째 direct pointer 읽기 (맞으면 7점. 안 풀면 0점 풀리면 4점) Yes
2.2 두 번째 diret pointer 쓰기 (맞으면 7점, 안 풀면 0점, 틀리면 4점) No
2.3 indirect pointer 읽기 (맞으면 7점, 안 풀면 0점, 풀리면 -4점) No
2.4 indirect pointer 쓰기 (맞으면 7점, 안 풀면 0점, 틀리면 4점) No
A2.
파일 시스템과 inode 구조에 대해 더 자세히 설명해보겠습니다. 주어진 코드와 조건을 기반으로 각 질문을 분석해 보겠습니다.
### 주어진 조건 요약
1. 하나의 블록 크기는 4KB입니다.
2. 캐시와 버퍼링이 없다고 가정합니다.
3. inode는 두 개의 direct pointer와 하나의 indirect pointer를 가지고 있습니다.
4. 파일을 4KB씩 두 번 읽습니다.
### 코드 분석
my_fd = open("/foo/bar", O_RDONLY);
for (i = 0; i < 2; i++)
read(my_fd, buf, 4096);
이 코드는 파일 `/foo/bar`을 읽기 전용으로 엽니다. 그런 다음 4KB씩 두 번 읽습니다.
### inode 포인터 구조
- **Direct pointer**: 파일의 데이터 블록을 직접 가리키는 포인터.
- **Indirect pointer**: 데이터 블록의 주소를 저장한 블록을 가리키는 포인터. 파일이 크거나 많은 블록을 필요로 할 때 사용됩니다.
inode는 두 개의 direct pointer와 하나의 indirect pointer를 가지고 있습니다. direct pointer는 첫 번째와 두 번째 데이터 블록을 직접 가리킵니다. 파일이 두 개 이상의 블록을 필요로 하면, 세 번째 블록부터는 indirect pointer를 통해 접근합니다.
### 각 질문에 대한 설명
#### 2.1 두 번째 direct pointer 읽기
첫 번째 4KB를 읽을 때는 첫 번째 direct pointer를 사용합니다. 두 번째 4KB를 읽을 때는 두 번째 direct pointer를 사용합니다. 따라서 두 번째 direct pointer를 읽는 동작이 발생합니다.
**답변:** Yes
#### 2.2 두 번째 direct pointer 쓰기
이 코드에서는 파일을 읽기만 하고 있습니다. 파일을 읽는 동안 inode의 포인터를 수정하지 않습니다. 따라서 두 번째 direct pointer를 쓰는 동작은 발생하지 않습니다.
**답변:** No
#### 2.3 indirect pointer 읽기
파일을 읽을 때 두 개의 4KB 블록을 읽습니다. 두 개의 direct pointer만으로도 8KB를 커버할 수 있습니다. 따라서 indirect pointer를 읽을 필요가 없습니다. indirect pointer는 두 개의 direct pointer로 접근할 수 있는 용량(8KB)을 초과하는 경우에 사용됩니다.
**답변:** No
#### 2.4 indirect pointer 쓰기
마찬가지로, 파일을 읽는 동안에는 쓰기 동작이 발생하지 않습니다. 따라서 indirect pointer를 쓰는 동작도 발생하지 않습니다.
**답변:** No
### 요약표
| 동작 | Yes/No |
|----------------------------|--------|
| 두 번째 direct pointer 읽기 | Yes |
| 두 번째 direct pointer 쓰기 | No |
| indirect pointer 읽기 | No |
| indirect pointer 쓰기 | No |
이제 각 질문에 대한 이유와 답변을 더 명확히 이해할 수 있기를 바랍니다.
Q2-1.
다음 코드와 같이 /foo/bar 파일을 새로 생성하고 쓰는 과정에서 발생하는 동작과 발생하지 않는 동작을 아래 표에 Yes 또는 No로 구분하시오.
• 하나의 블록은 4KB 크기를 갖는다고 가정
• Page cache 등의 캐쉬와 버퍼링은 없다고 가정
• inode는 두 개의 direct pointer, 하나의 indirect pointer를 갖고 있다고 가정
my_fd = open("/foo/bar", O_CREAT);
for ( i = 0; i < 2; i++ )
write (my_fd, buf, 4096);
2.1 foo 디렉토리의 inode 읽기 (맞으면 7점. 안 풀면 0점 풀리면 4점) Yes
2.2 foo 디렉토리의 inode 쓰기 (맞으면 7점, 안 풀면 0점, 틀리면 4점) Yes
2.3 root 디렉토리의 indoe 읽기 (맞으면 7점, 안 풀면 0점, 풀리면 -4점) Yes
2.4 root 디렉토리의 inode 쓰기 (맞으면 7점, 안 풀면 0점, 틀리면 4점) No
A 2-1.
주어진 코드와 가정을 바탕으로, 각 동작이 발생하는지 여부를 판단하겠습니다. 다음은 각 단계에서 발생하는 동작을 분석한 결과입니다.
1. **foo 디렉토리의 inode 읽기**:
- `/foo/bar` 파일을 생성하려면, 먼저 `/foo` 디렉토리를 찾아야 합니다. 이를 위해 `/foo` 디렉토리의 inode를 읽어야 합니다.
- **결론**: Yes
2. **foo 디렉토리의 inode 쓰기**:
- `/foo/bar` 파일을 생성할 때, `foo` 디렉토리에 새로운 항목(`bar`)이 추가되므로, `foo` 디렉토리의 inode가 수정됩니다.
- **결론**: Yes
3. **root 디렉토리의 inode 읽기**:
- 경로 탐색을 위해 `/`의 inode를 읽어야 합니다. 즉, 파일 경로의 첫 부분인 `/`을 확인하기 위해 root 디렉토리의 inode를 읽는 과정이 필요합니다.
- **결론**: Yes
4. **root 디렉토리의 inode 쓰기**:
- root 디렉토리 자체에는 변화가 없으므로 root 디렉토리의 inode를 쓸 필요가 없습니다. `foo` 디렉토리와 `bar` 파일의 생성은 root 디렉토리와 직접적으로 관련이 없습니다.
root 디렉토리의 inode를 직접적으로 쓰는 경우는 일반적으로는 드뭅니다. root 디렉토리는 시스템 부팅 시에 생성되고, 시스템의 파일 및 디렉토리 구조를 정의하는 역할을 합니다. 보안 및 시스템의 안정성을 고려할 때, 일반적으로 사용자 또는 프로그램이 root 디렉토리의 inode를 직접적으로 수정하는 것은 권장되지 않습니다.
- **결론**: No
결론적으로, 각 질문에 대한 답은 다음과 같습니다:
| 동작 | Yes/No |
|--------------------------------------|--------|
| 2.1 foo 디렉토리의 inode 읽기 | Yes |
| 2.2 foo 디렉토리의 inode 쓰기 | Yes |
| 2.3 root 디렉토리의 inode 읽기 | Yes |
| 2.4 root 디렉토리의 inode 쓰기 | No |
Q3.
네 개의 Logical Block 10, 100, 201, 1000의 데이터 a, b, c, d가 Flash 기반 SSD의 물리 페이지에 다음과 같이 저장되어 있다.
Block: 0 1 2
Page: 00 01 02 03 04 05 06 07 08 09 10 11
Content: a b c d
State: E E E E V V V V i i i i
3.1 SSD가 위 그림과 같을 때, 페이지 기반 매핑을 사용하는 FTL의 Mapping Table을 작성하시오. (7점)
3.2 <문제 3.1>의 상태에서 Logical Block 100에 새 데이터가 써졌을 때 페이지 기반 매핑을 사용하는 <문제 3.1>의 Mapping Table이 수정된 결과를 쓰시오. (7점)
3.3 SSD가 위 그림과 같을 때 블록 기반 매핑을 사용하는 FTL의 Mapping Table을 작성 하시오. (7점)
3.4 <문제 3.3>의 상태에서 Logical Block 100에 새 데이터가 써졌을 때 블록 기반 매핑 을 사용하는 <문제 3.3>의 Mapping Table이 수정된 결과를 쓰시오. (7점)
A 3.
### 3.1 SSD가 위 그림과 같을 때, 페이지 기반 매핑을 사용하는 FTL의 Mapping Table
#### 초기 Mapping Table (페이지 기반):
- Logical Block 10: Physical Page 04
- Logical Block 100: Physical Page 05
- Logical Block 201: Physical Page 06
- Logical Block 1000: Physical Page 07
```plaintext
+----------------+-----------------+
| Logical Block | Physical Page |
+----------------+-----------------+
| 10 | 04 |
| 100 | 05 |
| 201 | 06 |
| 1000 | 07 |
+----------------+-----------------+
```
### 3.2 <문제 3.1>의 상태에서 Logical Block 100에 새 데이터가 써졌을 때 페이지 기반 매핑을 사용하는 <문제 3.1>의 Mapping Table이 수정된 결과
#### 수정된 Mapping Table (페이지 기반):
- Logical Block 10: Physical Page 04
- Logical Block 100: Physical Page **08** (새 페이지에 기록)
- Logical Block 201: Physical Page 06
- Logical Block 1000: Physical Page 07
```plaintext
+----------------+-----------------+
| Logical Block | Physical Page |
+----------------+-----------------+
| 10 | 04 |
| 100 | 08 |
| 201 | 06 |
| 1000 | 07 |
+----------------+-----------------+
```
### 3.3 SSD가 위 그림과 같을 때 블록 기반 매핑을 사용하는 FTL의 Mapping Table
#### 초기 Mapping Table (블록 기반):
- Logical Block 10: Physical Block 0, Page 04
- Logical Block 100: Physical Block 0, Page 05
- Logical Block 201: Physical Block 0, Page 06
- Logical Block 1000: Physical Block 0, Page 07
```plaintext
+----------------+-----------------+-------------+
| Logical Block | Physical Block | Page Offset |
+----------------+-----------------+-------------+
| 10 | 0 | 04 |
| 100 | 0 | 05 |
| 201 | 0 | 06 |
| 1000 | 0 | 07 |
+----------------+-----------------+-------------+
```
### 3.4 <문제 3.3>의 상태에서 Logical Block 100에 새 데이터가 써졌을 때 블록 기반 매핑을 사용하는 <문제 3.3>의 Mapping Table이 수정된 결과
새로운 데이터가 쓰여진 논리 블록 100은 이전에 사용되던 블록이 아닌 새로운 블록에 매핑되어야 합니다. 따라서 새로운 블록에 기록되고, 이전에 사용되던 블록은 무효화되어야 합니다.
#### 수정된 Mapping Table (블록 기반):
- Logical Block 10: Physical Block 0, Page 04
- Logical Block 100: Physical Block **1**, Page 00 (새로운 블록에 쓰임)
- Logical Block 201: Physical Block 0, Page 06
- Logical Block 1000: Physical Block 0, Page 07
```plaintext
+----------------+-----------------+-------------+
| Logical Block | Physical Block | Page Offset |
+----------------+-----------------+-------------+
| 10 | 0 | 04 |
| 100 | 1 | 00 |
| 201 | 0 | 06 |
| 1000 | 0 | 07 |
+----------------+-----------------+-------------+
```
Q 3-1.
네 개의 Logical Block 100, 101, 1000, 1001의 데이터 a, b, c, d가 Flash 기반 SSD의 물리 페이지에 다음과 같이 저장되어 있다.
Block: 0 1 2
Page: 00 01 02 03 04 05 06 07 08 09 10 11
Content: a b c d
State: E E E E V V V V i i i i
3.1 SSD가 위 그림과 같을 때, 페이지 기반 매핑을 사용하는 FTL의 Mapping Table을 작성하시오. (7점)
3.2 <문제 3.1>의 상태에서 Logical Block 101에 새 데이터가 써졌을 때 페이지 기반 매핑을 사용하는 <문제 3.1>의 Mapping Table이 수정된 결과를 쓰시오. (7점)
3.3 SSD가 위 그림과 같을 때 블록 기반 매핑을 사용하는 FTL의 Mapping Table을 작성 하시오. (7점)
3.4 <문제 3.3>의 상태에서 Logical Block 101 에 새 데이터가 써졌을 때 블록 기반 매핑 을 사용하는 <문제 3.3>의 Mapping Table이 수정된 결과를 쓰시오. (7점)
A 3-1.
3.1 SSD가 위 그림과 같을 때, 페이지 기반 매핑을 사용하는 FTL의 Mapping Table을 작성하겠습니다.
### 페이지 기반 매핑의 초기 Mapping Table:
- Logical Block 100: Physical Page 04
- Logical Block 101: Physical Page 05
- Logical Block 1000: Physical Page 06
- Logical Block 1001: Physical Page 07
```plaintext
+----------------+-----------------+
| Logical Block | Physical Page |
+----------------+-----------------+
| 100 | 04 |
| 101 | 05 |
| 1000 | 06 |
| 1001 | 07 |
+----------------+-----------------+
```
3.2 <문제 3.1>의 상태에서 Logical Block 101에 새 데이터가 써졌을 때 페이지 기반 매핑을 사용하는 <문제 3.1>의 Mapping Table이 수정된 결과를 쓰겠습니다.
### 수정된 Mapping Table (페이지 기반):
- Logical Block 100: Physical Page 04
- Logical Block 101: Physical Page **08** (새 페이지에 기록)
- Logical Block 1000: Physical Page 06
- Logical Block 1001: Physical Page 07
```plaintext
+----------------+-----------------+
| Logical Block | Physical Page |
+----------------+-----------------+
| 100 | 04 |
| 101 | 08 |
| 1000 | 06 |
| 1001 | 07 |
+----------------+-----------------+
```
3.3 SSD가 위 그림과 같을 때 블록 기반 매핑을 사용하는 FTL의 Mapping Table을 작성하겠습니다.
### 블록 기반 매핑의 초기 Mapping Table:
- Logical Block 100: Physical Block 0, Page 04
- Logical Block 101: Physical Block 0, Page 05
- Logical Block 1000: Physical Block 0, Page 06
- Logical Block 1001: Physical Block 0, Page 07
```plaintext
+----------------+-----------------+-------------+
| Logical Block | Physical Block | Page Offset |
+----------------+-----------------+-------------+
| 100 | 0 | 04 |
| 101 | 0 | 05 |
| 1000 | 0 | 06 |
| 1001 | 0 | 07 |
+----------------+-----------------+-------------+
```
3.4 <문제 3.3>의 상태에서 Logical Block 101에 새 데이터가 써졌을 때 블록 기반 매핑을 사용하는 <문제 3.3>의 Mapping Table이 수정된 결과를 쓰겠습니다.
### 수정된 Mapping Table (블록 기반):
- Logical Block 100: Physical Block 0, Page 04
- Logical Block 101: Physical Block **1**, Page 00 (새로운 블록에 쓰임)
- Logical Block 1000: Physical Block 0, Page 06
- Logical Block 1001: Physical Block 0, Page 07
```plaintext
+----------------+-----------------+-------------+
| Logical Block | Physical Block | Page Offset |
+----------------+-----------------+-------------+
| 100 | 0 | 04 |
| 101 | 1 | 00 |
| 1000 | 0 | 06 |
| 1001 | 0 | 07 |
+----------------+-----------------+-------------+
```
이렇게 각 문제의 초기 매핑 테이블과 수정된 매핑 테이블을 정리하였습니다.
Q4.
데드락 발생 안하게 세마포어 사용한 코드 수정하고 이유 쓰기
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t sem1, sem2;
void* thread1(void* arg) {
sem_wait(&sem1);
printf("Thread 1\n");
sem_post(&sem2);
return NULL;
}
void* thread2(void* arg) {
sem_wait(&sem2);
printf("Thread 2\n");
sem_post(&sem1);
return NULL;
}
int main() {
pthread_t tid1, tid2;
sem_init(&sem1, 0, 0);
sem_init(&sem2, 0, 0);
pthread_create(&tid1, NULL, thread1, NULL);
pthread_create(&tid2, NULL, thread2, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
sem_destroy(&sem1);
sem_destroy(&sem2);
return 0;
}
이 코드에서 데드락이 발생할 수 있는 상황은 다음과 같습니다:
1. `thread1`이 `sem1`을 잠근 상태에서 `thread2`가 `sem2`를 잠길 경우, `thread1`은 `sem2`를 기다리고 있고 `thread2`는 `sem1`을 기다리는 상황이 발생할 수 있습니다.
2. 두 스레드가 각자의 세마포어를 해제하기 전에 종료될 경우, 다음 실행에 문제가 발생할 수 있습니다.
**수정된 코드:**
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t sem;
void* thread1(void* arg) {
sem_wait(&sem);
printf("Thread 1\n");
sem_post(&sem);
return NULL;
}
void* thread2(void* arg) {
sem_wait(&sem);
printf("Thread 2\n");
sem_post(&sem);
return NULL;
}
int main() {
pthread_t tid1, tid2;
sem_init(&sem, 0, 1); // 세마포어를 1로 초기화
pthread_create(&tid1, NULL, thread1, NULL);
pthread_create(&tid2, NULL, thread2, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
sem_destroy(&sem);
return 0;
}
수정된 코드에서는 세마포어를 하나로 통합하여 데드락의 가능성을 줄였습니다. 이렇게 하면 한 번에 한 스레드만이 세마포어를 획득할 수 있습니다. 또한, 각 스레드가 세마포어를 해제하도록 보장하여 리소스 누수를 방지합니다.
세마포어를 1로 초기화함으로써 한 번에 하나의 스레드만이 세마포어를 통과할 수 있도록 보장합니다. 따라서 데드락의 가능성을 제거하고, 리소스의 안전한 공유를 보장합니다.
A4.
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
sem_t sem1, sem2;
void* thread1(void* arg) {
sem_wait(&sem1);
printf("Thread 1: Acquired sem1\n");
usleep(100000); // 100 milliseconds
sem_wait(&sem2);
printf("Thread 1: Acquired sem2\n");
// 작업 수행
sem_post(&sem2);
printf("Thread 1: Released sem2\n");
sem_post(&sem1);
printf("Thread 1: Released sem1\n");
return NULL;
}
void* thread2(void* arg) {
sem_wait(&sem2);
printf("Thread 2: Acquired sem2\n");
usleep(100000); // 100 milliseconds
sem_wait(&sem1);
printf("Thread 2: Acquired sem1\n");
// 작업 수행
sem_post(&sem1);
printf("Thread 2: Released sem1\n");
sem_post(&sem2);
printf("Thread 2: Released sem2\n");
return NULL;
}
int main() {
pthread_t tid1, tid2;
sem_init(&sem1, 0, 1); // 세마포어1 초기화 (초기 값: 1)
sem_init(&sem2, 0, 1); // 세마포어2 초기화 (초기 값: 1)
pthread_create(&tid1, NULL, thread1, NULL);
pthread_create(&tid2, NULL, thread2, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
sem_destroy(&sem1);
sem_destroy(&sem2);
return 0;
}
이 코드에서는 두 개의 세마포어 `sem1`과 `sem2`를 사용하여 각 스레드가 자원에 접근할 때 상호 배제를 합니다. 각 스레드는 다음과 같은 순서로 세마포어를 획득하고 해제합니다:
1. 스레드 1은 세마포어 `sem1`을 획득한 후 `sem2`를 획득합니다.
2. 스레드 2는 세마포어 `sem2`를 획득한 후 `sem1`을 획득합니다.
이렇게 각 스레드가 서로 다른 순서로 세마포어를 획득하므로 데드락이 발생하지 않습니다.
Q5.
inode, 비트맵, 데이터 블록 수정시 inconsistency 발생 여부 참거짓 문제
A5.
1. **inode 수정 시 inconsistency 발생 여부**:
- 판단: 거짓(False)
- 이유: 일반적으로 inode의 수정은 원자적인 작업으로 처리됩니다. 파일 시스템은 inode를 수정하는 동안 어떤 고장이나 중단이 발생하더라도, 해당 inode의 변경 사항은 완전하게 반영되거나 완전히 취소됩니다. 따라서 inode를 수정하는 동안 inconsistency가 발생하지 않습니다.
2. **비트맵 수정 시 inconsistency 발생 여부**:
- 판단: 참(True)
- 이유: 비트맵을 수정하는 동안 시스템이 고장나면, 할당된 데이터 블록의 정보가 비트맵에 반영되지 않을 수 있습니다. 이 경우 데이터 블록이 실제로 할당되었지만 비트맵에는 할당되지 않은 상태로 남아 있게 되어 inconsistency가 발생합니다.
3. **데이터 블록 수정 시 inconsistency 발생 여부**:
- 판단: 참(True)
- 이유: 데이터 블록을 수정하는 동안 시스템이 고장나면, 변경된 데이터가 제대로 디스크에 기록되지 않을 수 있습니다. 이로 인해 파일의 내용과 디스크에 저장된 내용 사이에 불일치가 발생할 수 있습니다.
Q 6.
inode, 데이터 블록 수정 위치에 대한 심플 파일 시스템 기반 문제야
A 6.
간단히 말씀드리자면, 파일 시스템에서는 파일을 저장할 때 두 가지 주요 요소가 있어요. 하나는 파일의 정보를 담고 있는 메타데이터, 다른 하나는 실제 파일 내용이 저장되는 데이터 블록이에요.
메타데이터에는 파일의 이름, 크기, 소유자, 권한 등이 들어가요. 이 정보는 일반적으로 인덱 블록에 저장돼요. 그리고 인덱 블록은 파일이 저장된 위치를 가리키는 역할을 합니다.
데이터 블록은 실제 파일 내용을 담고 있어요. 파일이 크면 여러 데이터 블록에 걸쳐 저장될 수 있어요.
파일을 수정할 때, 먼저 해당 파일의 메타데이터를 수정하고, 그 다음에는 데이터 블록을 수정해요. 이때 인덱 블록을 통해 데이터 블록의 위치를 찾아가게 되요.
간단한 파일 시스템에서는 이런 과정으로 파일을 수정하고 관리합니다.
Q7.
log structure 문제
**문제:**
주어진 로그 데이터를 기반으로 다음 질문에 답하십시오.
```plaintext
Timestamp Level Message
---------------------------------------------------------------
2024-06-10 10:15:32 INFO User 'Alice' logged in.
2024-06-10 10:20:45 WARNING Disk space running low.
2024-06-10 10:25:03 ERROR Database connection failed.
2024-06-10 10:30:12 INFO User 'Bob' logged in.
2024-06-10 10:35:28 ERROR File not found: report.docx.
2024-06-10 10:40:09 INFO User 'Alice' logged out.
2024-06-10 10:45:17 INFO User 'Charlie' logged in.
```
1. 10시 이후에 발생한 모든 로그 이벤트의 수는 얼마입니까?
2. 가장 최근에 발생한 경고(WARNING) 메시지의 타임스탬프는 언제입니까?
3. 오류(ERROR) 메시지를 포함하는 로그 이벤트의 백분율은 얼마입니까?
이 문제를 풀려면 주어진 로그 데이터를 읽고 해당하는 질문에 대한 답을 추론하면 됩니다.
A7.
물론입니다. 주어진 로그 데이터를 바탕으로 각 질문에 대한 답을 제공하겠습니다.
1. 10시 이후에 발생한 모든 로그 이벤트의 수는 얼마입니까?
- 답: 5개입니다. (10:15:32, 10:20:45, 10:25:03, 10:30:12, 10:35:28)
2. 가장 최근에 발생한 경고(WARNING) 메시지의 타임스탬프는 언제입니까?
- 답: 2024-06-10 10:20:45 입니다.
3. 오류(ERROR) 메시지를 포함하는 로그 이벤트의 백분율은 얼마입니까?
- 답: 전체 로그 이벤트 중 오류 메시지가 1개 있으므로, 백분율은 20%입니다.
Q7-1.
log 구조 사용 장점 2가지
A7-1.
Log 구조는 데이터를 기록할 때 순차적으로 기록하는 방식을 말합니다. 여기에는 두 가지 주요 장점이 있습니다:
1. **성능 향상**: 데이터를 연속적으로 기록하기 때문에 디스크 I/O 작업이 최소화됩니다. 이는 특히 디스크의 회전 속도에 영향을 받는 기술에서 효과적입니다. 연속적인 기록은 디스크 헤드의 이동을 최소화하여 성능을 향상시킵니다.
2. **복구 용이성**: Log 구조에서는 각각의 데이터 변경 사항을 로그에 기록하므로 시스템이 충돌하거나 중단되었을 때 데이터베이스를 이전 상태로 복구하기가 쉽습니다. 로그 파일에는 각 트랜잭션의 변경 내용이 기록되어 있으므로, 이를 사용하여 시스템을 이전 상태로 복구할 수 있습니다.