[Jungle][TIL] 240528 fsync | MLFQ scheduler | KMP 알고리즘

somi·2024년 5월 28일
0

[Krafton Jungle]

목록 보기
59/68

FSYNC() ?

이 함수가 파일 시스템에서 어떤 역할을 하는가?

fsync()를 사용할 때 고려해야 할 성능상의 영향은 무엇인가??

파일 시스템에서 데이터의 무결성을 보장하기 위해 사용되는 시스템 콜 But 디스크 쓰기 작업으로 인한 성능 저하 고려해야 함

  • 파일 디스크립터로 저장된 파일의 변경사항을 디스크에 즉시 반영하도록 요청
  • 메모리에 있는 파일의 변경된 내용(버퍼에 캐시된 데이터)을 디스크에 강제로 쓰게 함
  • 시스템이 비정상적으로 종료되더라도 해당 파일의 데이터가 최신 상태로 유지되게 하여 데이터 손실을 방지하는 역할
  • 파일의 변경사항을 디스크에 즉시 반영하려면 디스크에 물리적인 쓰기 작업이 필요 => 상대적으로 느린 작업 => fsync() 호출은 프로그램의 실행 속도를 늦출 수 있다.
  • 작은 데이터를 자주 쓰는 애플리케이션에선느 특히 성능 저하가 두드러질 수 있다.

fsync() 함수는 열려 있는 파일 디스크립터와 관련된 모든 수정된 데이터를 디스크에 동기화함!
파일의 쓰기 작업이 메모리에만 저장되는 것이 아니라 실제 저장 매체에도 반영되도록 보장한다.
-> 시스템이 예기치 않게 중단되더라도 데이터의 무결성을 보장!

디스크 I/O 작업이 증가하여 시스템의 전반적인 성능 저하가 발생할 수 있다. -> 빈번한 fsync()호출은 디스크의 작업 부하를 증가시키고 결과적으로 시스템의 반응 속도를 늦출 수 있다.

예시)

데이터의 무결성이 매우 중요한 금융 거래 정보 처리
-> 모든 변경사항에 대해 fsync()를 호출해서 데이터 손실 위험을 최소화할 수 있다.
반면, 데이터의 무결성이 상대적으로 덜 중요한 로그 파일을 다룰 때는 fsync() 호출을 줄여 성능을 개선할 수 있다.


멀티레벨 피드백 큐(MLFQ) 스케줄러를 구현하는 시스템에 5개의 프로세스가 있을 때

P1: 도착 시간 5, CPU 버스트 14
P2: 도착 시간 8, CPU 버스트 2
P3: 도착 시간 25, CPU 버스트 5
P4: 도착 시간 27, CPU 버스트 2
P5: 도착 시간 29, CPU 버스트 2

참고) Context switching 시간: 1초라고 하자.

P3가 가장 마지막에 완료되는 프로세스이다.


KMP 알고리즘

스트링 : abcabgabcaabcabcabgabcaef
패턴 : abcabgabcae

skip 배열 : [0, 0, 0, 0, 1, 2, 0, 1, 2, 3, 4, 0]
count: 4

def kmp_match(txt: str, pat: str) -> int:
    # 패턴을 검색하는 위치
    pt = 1
    # 패턴에서 일치하는 문자열의 위치
    pp = 0
    
    # 건너뛰기 정보를 저장하는 배열
    skip = [0] * (len(pat) + 1)
    skip[pt] = 0
    
    # 건너뛰기 표를 만드는 과정
    while pt != len(pat):
        if pat[pt] == pat[pp]:
            pt += 1
            pp += 1
            skip[pt] = pp
        elif pp == 0:
            pt += 1
            skip[pt] = pp
        else:
            pp = skip[pp]

    print("skip : " + ", ".join(map(str, skip)))
    
    pt = pp = 0
    count = 0  # 추가적인 문자 비교 횟수
    
    # 본격적으로 텍스트에서 패턴을 검색하는 과정
    while pt != len(txt) and pp != len(pat):
        if txt[pt] == pat[pp]:
            pt += 1
            pp += 1
        elif pp == 0:
            pt += 1
        else:
            pp = skip[pp]
            count += 1
    
    print("count: " + str(count))
    
    # 패턴이 발견된 경우 그 시작 위치를 반환
    return pt - pp if pp == len(pat) else -1

if __name__ == '__main__':
    s1 = input('텍스트를 입력하세요.: ')
    s2 = input('패턴을 입력하세요.: ')
    idx = kmp_match(s1, s2)
    
    if idx == -1:
        print('텍스트 안에 패턴이 존재하지 않습니다.')
    else:
        print(f'{(idx+1)}번째 문자가 일치합니다.')

커널 모드에서 실행될 수 있는 작업?

공유 자원 관리, 하드웨어 장치 제어, 시스템 콜 처리, 프로세스 및 쓰레드 관리, 메모리 관리
: 프로세스 생성, 스케줄링, 종료 등 프로세스와 쓰레드의 생명주기 관리
: 가상 메모리 관리, 페이지 교체 알고리즘 실행 등 메모리의 할당 및 회수도 관리

이러한 작업들이 사용자 모드에서 실행되지 않는 이유 : 시스템의 안정성과 보안 유지 및 데이터의 일관성 유지

  • 공유 자원 관리 -> 주로 커널 모드에서 실행
    파일 시스템, 메모리, 프린터 등과 같은 자원은 여러 프로세스에 의해 동시에 요청될 수 있으며, 이에 대한 접근과 사용을 적절히 관리하는 것은 필수적이다.

  • 커널 모드에서는 이러한 자원들에 대한 접근을 제어하고 충돌이나 데이터 손상을 방지한다.

  • 사용자 모드에서는 이러한 공유 자원의 직접 관리를 수행하지 않는다. 이러한 사용자, 프로세스가 직접 자원에 접근할 경우 데이터의 일관성과 안정성이 위협 받을 수 있다.


운영체제에서 context switching이 발생하는 과정에서 어떤 정보가 복원되는가?

context switching: 운영체제는 현재 실행 중인 프로세스의 상태를 저장하고, 다음에 실행할 프로세스의 상태를 복원한다.
-> 각 프로세스가 중단된 지점부터 다시 실행될 수 있다.

저장되는 정보에는 프로세스의 프로그램 카운터, 레지스터 상태, 메모리 관리 정보, 열린 파일 목록 등이 포함된다.

  • Program Counter: 현재 실행 중인 명령어의 주소를 저장한다. 프로세스가 다시 실행될 때 어디서부터 실행을 재개해야 하는지 결정한다.
  • Registers: CPU 레지스터의 내용, 즉 프로세스가 사용중이던 모든 레지스터의 값을 저장한다. SP, flag register, 일반 목적 레지스터 등등
  • Memory Management Information: 프로세스의 주소 공간 정보, 페이지 테이블, 세그먼트 테이블 등의 메모리 관리 관련 정보 저장. => 프로세스가 사용되는 메모리 영역을 정확히 관리하기 위해
  • PCB, Process Control Block: 프로세스의 상태, PID, priority, 스케줄링 정보, 계정 정보 등 프로세스와 관련된 다양한 정보를 포함하는 구조체.
    -> PCB는 운영체제가 각 프로세스를 관리하는데 사용됨
  • Open File Descriptor : 프로세스가 열어 높은 파일에 대한 정보가 저장 -> 프로세스가 파일 입출력을 계속해서 수행할 수 있도록!
  • CPU state: CPU의 상태 레지스터 등, CPU의 현재 상태를 나타내는 모든 정보를 저장

profile
📝 It's been waiting for you

0개의 댓글