하드 링크 (Hard Link) 와 심볼릭 링크 (Symbolic Link) 는 운영체제 파일시스템을 이해하는데 기초적인 개념이다.

아마 윈도우를 많이 사용한다면, 원본 - 바로 가기 개념이 떠오를 수 있지만 다소 차이가 있다.

 

  • Hard Link
    • 원본 파일과 동일한 inode 를 가지며 원본 파일이 삭제되더라도 링크 파일을 여전히 사용 가능하다
    • ln [Source] [Target] 명령어로 생성 가능
    • 위치 정보를 가지고 있는 이름을 여러 개 생성하는 개념이다. 그렇기 때문에 한 파일을 지워도 하드에서 해당 위치를 찾아갈 수 있다
  • Symbolic Link
    • 원본 파일의 이름을 가리키는 링크로 원본 파일이 삭제되면 사용 불가능하다
    • 전혀 다른 파일이라도 가리키는 원본 파일 이름이 같으면 계속 사용 가능하다
    • ln -s [Source] [Target] 명령어로 생성 가능. Source 를 가리키는 심볼릭 링크 Target 을 만든다
    • Source 파일을 수정하면 심볼릭 링크인 Target 파일도 수정된다
      • Target 파일을 수정해도 Source 파일이 같이 수정된다
    • 위치 정보를 갖고 있는 파일명을 또 다른 이름으로 가리키는 포인터의 개념이다
      • 하드링크는 한 위치 정보를 또 다른 이름으로 가리키는 개념

 

특히 리눅스 환경에서는 개발 환경 구성 시, 심볼릭 링크를 사용해서 파일 경로를 간편하게 관리하기도 한다

(루트 디렉토리 내에 심볼릭 링크를 구성해서 마운트한 파일 시스템을 연결시킨다던지)

 

잘 알아두면 유용하게 사용할 수 있다. :)

 


Unix 기반의 운영체제는 File System 에 Access Permission 을 관리할 수 있는 장치를 갖고 있다.


이는 특정 사용자 또는 그룹에게 어떤 종류의 권한을 허용하는 가에 대한 정보를 저장하게 된다. 


파일 접근 권한에 대한 분류는 다음과 같이 나눌 수 있다.


 (1) 접근 대상에 대한 분류

 - User

 - Group

 - Others(public)


 (2) 접근 권한에 대한 분류

 - Read

 - Write

 - Execute


Unix 기반의 운영체제에서 File System 내의 모든 요소는 File 로 관리되기 때문에 각 파일이 위의 대상들 각각에 대한 권한을 모두 갖고 있다.

즉, 하나의 파일은 User / Group / Others 에 대한 Read / Write / Execute 권한을 전부 관리하게 된다.


먼저 각 접근 권한에 대해 알아보자.


Unix 시스템은 접근 권한을 bit 단위로 관리하며, 각 접근 권한은 다음 비트들에 매핑된다.


Read(4), Write(2), Execute(1)


이게 무슨 의미냐면, Unix 시스템은 위와 같은 이진 주소에 Access / Deny 정보를 관리한다는 뜻이다. 

즉, Read 는 4의 위치(2^2) 에서 1/0 으로 구분이 되며, Write 는 2의 위치(2^1), Execute 는 1의 위치(2^0) 에서 1/0 으로 권한 비트를 구별한다.


정리하자면 권한에 대한 비트는 다음과 같이 각각에 대한 Flag 값의 조합으로 이루어진다.


101 => Read(4 * 1) + Write(2 * 0) + Execute(1 * 1) => 5

111 => Read(4 * 1) + Write(2 * 1) + Execute(1 * 1) => 7


위와 같은 플래그 값으로 File System 의 권한을 나타낼 수 있으며, Unix File System 은 각 접근 대상 들에 대해 이를 똑같이 적용한다.


소유자(User)    /    그룹(Group)    /    공개(Public)

    rwx(7)                  rwx(7)                 rwx(7)


가령 위와 같이 정리되어 있을 경우 이 파일은 Permission Code 777 을 가졌다고 하며, 모든 소유자, 그룹, 공개된 사용자들에 대해 읽기(Read), 쓰기(Write), 실행(Execute) 권한을 모두 부여함을 뜻한다.



Permission 에 대한 권한은 chmod 명령어를 이용해서 변경할 수 있고, 다음과 같이 사용 가능하다.


chmod 755 /sample : /sample 폴더에 사용자(R, W, X), 그룹(R, X), 공개된 사용자(R, X) 권한을 부여한다.


chmod 사용에는 다음과 같은 옵션을 부여해서 같이 사용할 수 있다.


-c : 실제로 파일의 권한이 바뀐 파일만 자세히 기술한다. 

-f : 파일의 권한이 바뀔 수 없어도 에러 메시지를 출력하지 않는다. 

-v : 변경된 권한에 대해서 자세히 기술한다. 

-R : 디렉토리와 파일들의 권한을 재귀적으로 모두 바꾼다.


chmod 외에도 chown(파일의 소유자 및 소유 그룹변경) 명령어나 chgrp(파일의 사용자 그룹 변경) 명령어도 잘 사용되므로 알아두도록 하자.





프로세스 제어블록(Process Control Block)의 약어로 프로세스를 관리하는데 사용하는 OS의 자료구조이다.

운영체제는 프로세스를 PCB 단위로 관리하며 프로세스 스케줄링을 위한 정보를 PCB 를 통해 관리한다.


프로세스가 생성될 때마다 고유의 PCB 가 생성되며, 프로세스가 완료되면 PCB 는 제거된다.

프로세스 간 Switching 이 발생할 때, 운영체제는 PCB 를 이용해서 상태를 전이시킨다. (State Transition)


프로세스는 CPU가 처리하던 작업 내용들을 PCB에 저장하고, 

다음에 다시 CPU 를 점유하여 작업할 때 PCB로부터 해당 정보들을 CPU 에 넘겨와서 하던 작업을 진행한다.


PCB는 다음과 같은 데이터 구성을 갖고 있다.


- Process Identification Data

- Process State Data

- Process Control Data


PCB 는 다음과 같은 정보들을 저장하고 있다.


(1) Process ID : 프로세스를 구분하는 ID


(2) Process State : 각 State 들의 상태를 저장한다.


(3) Program Counter : 다음 Instruction 의 주소를 저장하는 카운터. CPU는 이 값을 통해 Process 의 Instruction 을 수행한다.


(4) Register : Accumulator, CPU Register, General Register 등을 포함한다.


(5) CPU Scheduling Information : 우선 순위, 최종 실행시간, CPU 점유시간 등이 포함된다.


(6) Memory Information : 해당 프로세스 주소공간(lower bound ~ upper bound) 정보를 저장.


(7) Process Information(페이지 테이블, 스케줄링 큐 포인터, 소유자, 부모 등)


(8) Device I/O Status(프로세스에 할당된 입출력 장치 목록, 열린 팔린 목록 등)


(9) Pointer : 부모/자식 프로세스에 대한 포인터, 자원에 대한 포인터 등


(10) Open File List : 프로세스를 위해 열려있는 파일의 리스트






 가상메모리(Virtual Memory)는 컴퓨터가 사용하는 메모리 관리 테크닉이다.

실제메모리를 추상화하여 가상 메모리에 올림으로써 프로세스들이 연속된 물리적 메모리 공간처럼 여기게 만들 수 있을 뿐만 아니라 실제 메모리보다 많은 크기의 메모리도 운용이 가능하다.


가상메모리 기술이 동작하기 위해서는 2가지 이슈가 있다.

하나는 가상 메모리를 물리 메모리에 매핑시키는 Address Translation이고, 다른 하나는 이 가상 공간에 대한 관리 이슈이다.


이러한 Virtual Memory 와 Physical Memory 의 매핑을 위한 기술로 Paging 기법이 사용된다.


페이징 기법은 컴퓨터가 메인 메모리에서 사용하기 위해 데이터를 저장하고 검색하는 메모리 관리 기법이다.

페이징 기법을 통해 컴퓨터의 물리적 메모리는 연속적으로 할당되어 존재할 필요가 없으며, 반대로 연속적으로 존재하지 않는 물리적 메모리라도 페이징 기법을 통해 연속적으로 존재하는 것처럼 이용될 수 있다.


페이징 방식에서는 가상 메모리 상의 주소 공간을 일정한 크기로 분할한다. 

주소공간은 페이지 단위로 나뉘어져있으며 실제 기억공간은 페이지 크기와 같은 프레임으로 나누어 사용한다.


 - Frame : 물리 메모리를 일정된 한 크기로 나눈 블록

 - Page : 가상 메모리를 일정된 한 크기로 나눈 블록


이 때 Frame 과 Page 의 크기는 동일하게 관리된다.

페이지의 크기는 크기는 시스템에 따라 다르며 크기가 작으면 메모리를 단편화하기 쉬워지지만 페이지의 갯수가 많아지기 때문에 페이지 단위의 입출력이 자주 발생하게 된다.


페이지가 하나의 프레임을 할당받으면, 물리 메모리에 위치하게 된다.

프레임을 할당받지 못한 페이지들은 외부저장장치에 저장되며, 마찬가지로 프레임과 같은 크기 단위로 관리된다.


페이징 기법에서 페이지는 페이지테이블(Page Table) 이라는 자료구조 형태로 관리된다.

Page Table 은 프로세스의 페이지 정보를 저장하고 있으며, 하나의 프로세스는 하나의 페이지 테이블을 가진다.

Page table 은 Index 를 키로 해당 페이지에 할당된 메모리(Frame)의 시작 주소를 Value 로 저장하고 있다.


페이지 테이블 엔트리(Page Table Entry)는 페이지 테이블의 레코드를 말한다.

PTE 의 각 필드에는 다음 내용들이 기록된다.


 - 페이지 기본 주소(Page base address)


 - 플래그 비트(Flag bit)

  - Accessed bit : 페이지에 대한 접근이 있었는지를 나타낸다.

  - Dirty bit : 페이지의 내용에 변경이 있었는지를 나타낸다.

  - Present bit : 현재 페이지에 할당된 프레임이 있는지를 나타낸다.

  - Read/Write bit : 읽기/쓰기에 대한 권한을 표시한다.


페이지의 크기는 하드웨어에 의해 정의되며 대게 2의 제곱으로 증가한다.



페이징 기법에서 동적 주소 변환 과정은 다음과 같다.


(1) 수행 중인 프로세스가 가상주소를 참조한다.


(2) 페이징 기법을 통해 페이지 p가 페이지 프레임 f에 있음을 알아낸다.


(3) 실주소 r = f(페이지 프레임) + d(오프셋) 를 구해낸다.


위와 같은 방식으로 페이지 테이블은 Virtual Memory 에서 Physical Memory 를 참조가능하도록 지원한다.



페이지 테이블은 사용을 위해서 메모리에 존재해야 하지만, 그렇게 되면 메모리 접근에 있어서 중복 호출이 일어나므로(페이지 테이블에 한번, 페이지테이블을 통한 실제 메모리에 한번), 대게 MMU 의 지원을 받아 매핑시키게 된다. 



(참고 : https://www.geeksforgeeks.org/operating-system-paging/

https://gabrieletolomei.wordpress.com/miscellanea/operating-systems/virtual-memory-paging-and-swapping/)


I/O Scheduling 은 운영체제가 여러 프로세스로부터 I/O 요청을 받았을 때 이에 대한 우선순위를 정해서 실행시켜주는 것을 말한다.

 

일반적으로 OS 내에 있는 스케줄러는 throughput 과 latency 를 고려하여 설계되며 하드디스크 검색으로 낭비되는 시간을 최소화하고, 우선적으로 필요한 프로세스들에게 I/O 요청을 할당하는 것이 주 목표이다.

 

I/O Scheduler 의 종류로는 다음과 같은 것들이 있다.

 

- Noop Scheduler : 커널이 스케줄링을 위해 별다른 작업을 하지 않는다. SSD 또는 RAID 디스크를 사용하는 경우 스케줄러의 동작이 오히려 디스크의 성능에 부하를 줄 수 있다는 점에 착안하였다.

 

- CFQ(Completely Fair Queueing) : 기본 스케줄러로, 각 프로세스마다 Round Robin 알고리즘에 의해 스케줄링이 수행된다. 각 작업을 마친 후 일정 time slice 만큼 기다린 후 다른 프로세스로 제어를 넘긴다. Synchronous 작업이 Asynchronous 작업보다 우선순위가 높다.

 

- Deadline : I/O 대기 시간의 한계를 정해놓고 데드라인이 가까운 작업부터 제어를 할당한다. 지연에 최적화되어있으며 I/O 가 몇몇 프로세스에 집중되어 있을 때 유용하기 때문에 Database 시스템에 주로 사용된다.

 

- Anticipatory : 연속된 read 요청의 경우 미리 처리량을 예측해서 요청을 스케줄링하는 방식으로 응답시간이 중요한 경우에 유용하다. 

 



Linux 계열의 운영체제는 EXT 라는 파일시스템 구조를 사용한다.


* EXT(Extended file system) : 리눅스 용으로 개발된 파일시스템으로 Minix 파일시스템의 한계를 극복하고자 만들어졌다.


* EXT2 

 : Linux 의 초창기 파일시스템 표준이다. TIMESTAMP 의 제약이 있으며 장애 발생시 파일 시스템 복구를 위한 fsck 도구를 갖고 있다.


- EXT2 inode : inode 는 파일 시스템의 가장 기본이 되는 단위이다. 

각각을 구분할 수 있는 고유번호를 가지고 파일의 데이터가 어느 블록의 어느 위치에 저장되어 있는지, 파일에 대한 접근권한, 파일의 최종 수정시간, 파일의 종류 등의 정보를 inode 테이블에 저장한다.

저장되는 정보는 모드, 소유자 정보, 크기, Timestamp, 데이터블록이다. 


- EXT2 super block : 슈퍼블록은 해당 파일 시스템의 기본적인 크기나 형태에 대한 정보를 저장한다. 슈퍼블록에 저장되는 항목은 다음과 같다.


 (1) Magic number : 마운트하는 소프트웨어에게 EXT2 파일 시스템의 슈퍼블록임을 확인하게하는 값이다.


 (2) Revision level : major level과 minor level 로 구성되어 있으며, mount 시스템이 file system 에서 지원되는지에 대한 버전 정보 확인을 위해 사용된다. 

 또한 이 정보를 이용해 호환성을 판단할 수 있다.


 (3) Mount count : 마운트 횟수와 최대마운트 횟수를 저장한다. 마운트가 실행될 때마다 카운트가 증가하며 이 값을 이용해 시스템 전체를 검사할 필요가 있는지 확인한다.


 (4) Block group number : 블록 그룹번호는 슈퍼 블록 복제본을 갖고 있는 블록 그룹의 번호를 나타낸다. 


 (5) Block size : 블록 크기는 File System 의 블록크기를 바이트 단위로 표시한다.


 (6) Blocks per group : 그룹에 속한 블록 수를 저장한다.


 (7) Free block : 파일 시스템 내부적으로 존재하는 프리블록 수를 나타낸다.


 (8) Free inode : 파일 시스템 내부적으로 존재하는 free inode 수를 나타낸다.


 (9) First inode : 리눅스 시스템의 첫번째 inode는 "/" 디렉토리 엔트리를 나타낸다.


- EXT2 group descriptor : 블록그룹에서 블록의 할당 상태를 나타내주는 비트맵이다. 블록을 할당하거나 해제할 경우 참조되는 정보로, block bitmap, inode bitmap, inode table 을 구성요소로 갖는다.

inode 비트맵은 블록 그룹에서 inode 할당상태를 나타내주는 비트맵으로 그 수는 블록 비트맵과 같은 block 의 수와 동일하다.


- EXT2 directory : EXT2 파일 시스템에서 디렉토리는 파일에 대한 접근 경로를 생성하고 저장한다.

directory 는 entry 의 list로 나타내어 지며, 엔트리 리스트에는 inode, 이름길이, 이름 정보가 저장된다.



* EXT3

 : 저널링을 지원하는 호환성 높은 파일시스템 구조이다. 온라인 상태에서 파일시스템을 확장 가능하며, directory 에 대한 tree 기반 indexing 을 제공한다.

쓰기 실행중 fsck 가 불가능한 단점이 있다.


 - 저널링(Journaling) 기술

기존의 EXT2는 시스템에 문제가 생기는 경우 파일시스템이 손상될 수 있는 문제점을 갖고 있었고, 이를 해결하기 위해 fsck(File System Check) 라는 도구를 사용하였다.

하지만 복구에는 시간이 오래걸리고, 복구하는 동안 시스템의 사용으 불가능한 단점이 있었다. 

EXT3는 이 단점을 해결하기 위한 저널링(Journaling) 기능을 사용하며, 이를 통해 파일 시스템의 무결성과 복구 기능을 갖추게 되었다.

저널링 기술은 파일 수정 이전에 로그에 내용을 저장하고, 로그를 바탕으로 수정 내용을 처리하는 Replay 과정을 거치며, 이런 파일 시스템의 특성을

Logging File System 이라고 한다.


 - 저널링(Journaling) 파일 시스템의 구조

저널링을 수행하기 위한 로그영역과 일반 파일 시스템 영역으로 나뉜다. Log는 Rolling File 형태의 구조로 관리되며, 이는 전용 스레드가 처리한다. 

로그에 대한 트랜잭션이 별도로 관리되며, 트랜잭션 내의 레코드 I/O 를 바탕으로 파일시스템이 관리된다.



* EXT4

 : Linux 파일시스템 표준으로, Timestamp 가 나노초단위로 개선되어 있다. 

 ext2, ext3 를 ext4 로 마운팅 가능하며 호환성이 뛰어나다. 다음과 같은 특징들을 지닌다.


 (1) 대형 파일 시스템 : 최대 1 Exabyte 까지의 볼륨을 지원한다.


 (2) Extent : 전통적인 Block mapping 을 대체하기 위한 extent 방식을 사용한다. inode 에 최대 4개의 extent를 할당해서 물리적으로 인접한 블록들을 묶어서 관리한다.


 (3) Allocate on flush : 데이터가 디스크에 실제로 쓰여지기까지 블록 할당을 지연시키는 기술이다. 하나의 파일에 대해 블록의 분산을 막을 수 있고 디스크 이동을 최소화시킬 수 있다. 다만 장애 시 충돌 가능성이 존재한다.


 (4) 디렉터리 제한 변경 : 하위 Directory 에 대한 제한이 32000개에서 64000개까지 늘어났다. 




참조 : http://egloos.zum.com/nix102guri/v/392605




운영체제는 시스템의 Disk partition 상에 파일들을 연속적이고 일정한 규칙을 갖고 저장하는데, 이러한 파일을 관리하는 규칙을 File System이라 한다.


FileSystem 의 구조


Unix/Linux 계열의 운영체제는 Tree 형태의 계층적인 파일구조를 구성한다. 다음은 File System 을 구성하는 요소들이다.


- Super block : 슈퍼블록은 FileSystem에 의존하는 정보를 가지며 FileSystem 의 크기 등과 같은 File System 의 전체적인 정보를 포함한다.


- inode(Index node) : 아이노드(inode)는 파일의 이름을 제외한 해당 파일의 모든 정보를 갖고 있다.

갖고있는 정보로는 파일의 소유권, 권한(Permission), 실제 데이터가 있는 물리적 주소, 파일의 형태, 크기, 링크 수, 수정/사용 시간 등이 있다.

파일 이름은 inode 의 번호와 함께 directory 안에 저장된다.

각 파일들은 1개씩의 inode를 갖고 있으며, 파일 시스템 내에서 파일의 이름을 key 로 식별되는 inode 숫자를 통해 식별 가능하다. (즉, inode는 파일 시스템 내에서 유일하다.)


- data block : 데이터블록은 inode 에 포함된다. inode 는 몇개의 data block 을 포함하고 있으며, 각 데이터 블록은 파일들의 데이터를 실제로 저장하고 있다.


- Directory block : 파일 이름과 inode 번호를 저장한다.


- Indirection block : 간접 블록은 추가적인 데이터 블록을 사용하기 위한 포인터들이 할당되는 공간이다. 

실제로 inode 는 적은 수의 데이터블록을 갖고 있으며 더 많은 데이터블록이 필요할 경우 이를 동적으로 가리킬 포인터가 저장된다.


- Hole : 홀은 inode 나 간접 블록 안의 데이터 블록의 주소로 특별한 값을 저장한다. 

hole 을 파일 안에 구조화되지만 hole 을 위한 실질적인 disk 공간은 할당되지 않는다. 단지 0바이트가 파일 안에서 특정 공간을 차지하고 있다고 가정하는 것이다.


위의 개념들 중에서 중요하고도 특징적인 개념은 Inode 의 개념이다.

파일시스템은 inode 를 참조하여 파일의 정보를 다룰 수 있다.


( * 참고로 현재 파일시스템 내의 Total Block / Free Block, Total Inode / Free Inode 정보는 [stat -f "파일이름"] 명령어를 통해 조회가능하다.)


또한 위의 내용들을 자세히 이용하기 위해서는 Nix 계열의 파일시스템인 EXT에 대해서도 알아야 한다. EXT에 대해선 다음 포스팅에 추가한다.





좀비 프로세스(Zombie Process)와 고아 프로세스(Orphan Process) 는 흔히 볼 수 있는 프로그래밍 퀴즈 테마의 하나이다.


Unix / Linux 계열의 운영체제에서 프로세스 들을 관리하는 특징적인 방법으로 인해 나타나는 특이한 형태의 프로세스를 말한다.


부모 프로세스가 자식 프로세스보다 먼저 종료되면 자식 프로세스는 고아 프로세스가 되며, 자식 프로세스가 먼저 종료되었지만 부모 프로세스가 자식 프로세스의 종료 상태를 회수하지 못했을 경우에 자식 프로세스를 좀비 프로세스라고 한다.


리눅스의 코딩 시 fork()를 통해 자식 프로세스를 만들면 fork의 리턴값이 되는 pid로 부모와 자식을 구분할 수 있다. (pid>0 이면 부모, pid == 0 이면 자식) 

 

자식 프로세스가 작업을 종료하면 고아 프로세스의 경우 리눅스 시스템 상의 init 프로세스가 wait을 통해 자원을 회수하여 PID 가 1로 변한다. (대부분의 Linux 에서 init 프로세스의 PID 는 1이기 때문이다.)

반면 좀비 프로세스의 경우 부모 프로세스에서 wait 시스템콜을 사용해줘야 리소스 유출을 방지할 수 있다.



#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
// Create a child process
int pid = fork();

if (pid > 0)
printf("in parent process");
// Note that pid is 0 in child process
// and negative if fork() fails
else if (pid == 0)
{
sleep(30);
printf("in child process");
}
return 0;
}




참조 : https://www.geeksforgeeks.org/zombie-and-orphan-processes-in-c/

(너무 좋은 예제라 참조하였다.)





단일 프로세스 & 쓰레드를 갖는 프로그램을 개발할 경우에는 신경쓸 일이 거의 없지만 여러 작업루틴이 동시에 수행되며, 공유 리소스에 접근하게 되는 동시성 프로그래밍을 할 경우에는 반드시 신경써주어야 할 부분이 바로


Mutual Exclusion (상호배제) 문제이다. 이는 공유 불가능한 자원을 동시에 사용하게 될 경우 발생할 수 있는 충돌을 방지하기 위해서 Critical Section 을 만들고, 해당 영역에서 데이터를 사용하게끔 하는 방법을 사용한다.


(1) 세마포어(Semaphore)


이렇게 공유자원에 대한 동시성 문제가 발생하였을 때, 즉 여러 개의 프로세스 또는 쓰레드가 동시접근하는 문제를 방지하기 위해 고안된 것이 바로 세마포어이다. 


세마포어란 리소스의 상태를 나타내는 카운터를 지정하여 다중 프로세스에서 행동을 조정 및 동기화 시킬 수 있는 기술이다. 

여러 프로세스가 접근 시 여러 개의 Lock 을 할당하여 동시에 허용 가능한 Counter 의 제한을 둔다. 카운터가 1개로 0 / 1의 값을 가질 때 Binary Semaphore 라하고 이는 Mutex와 동작이 같다.


(2) 뮤텍스(Mutex)


뮤텍스는 Lock 을 가지고 있을 때에만 공유자원에 접근이 가능하게끔 하는 로직이다. 

즉, 세마포어가 여러 개의 락을 두어 제한된 리소스 접근을 허용하는데 반해 뮤텍스는 오로지 한 개의 쓰레드/프로세스만 할당한다.



* 세마포어(Semaphore) 와 뮤텍스(Mutex) 의 차이점


- 세마포어는 주로 시스템적 범위에 적용이 되며 뮤텍스는 프로세스 내에서 적용이 된다. 

(물론 세마포어와 뮤텍스는 매커니즘의 개념이기 때문에 국한된다고 할 수는 없다.) 주로 뮤텍스는 프로세스 내 쓰레드간 자원 접근에 대하여 적용이 되며 Lock 한 쓰레드가 Unlock 도 해주어야 한다. 

반면 세마포어는 Lock 을 건 소유주가 아니더라도 Unlock 이 가능하다.


- 세마포어는 동기화 대상이 하나 이상일 때, 뮤텍스는 하나일 때 사용된다.


동기화 처리 로직은 Lock 을 수반하며 이 Lock 이 여러 개의 작업 큐 내에서 걸릴 때 DeadLock 이 생길 우려가 있다.


데드락은 임계 영역 내의 전역 리소스에 대해 복수 개의 Lock에 의해 처리가 지연되는 현상이다. 

대표적으로 Critical Section 에 접근하여 공유 자원을 처리하는 여러개의 로직이 서로에 대한 의존도(Dependency)를 가질 때 발생한다.


다음과 같은 상황을 가정해보자.




위의 그림에서 프로세스1 은 Resource 1을 선점하고 있으며, Resource 2에 대한 작업처리를 요구한다.

Resource 2에 대한 처리를 완료하면 Resource 1을 사용할 수 있도록 Critical Section 바깥으로 반환할 것이다.

반대로 프로세스2 는 Resouce 2를 선점하고 있으며 Resource 1에 대한 작업 처리를 마친 후 Resource 2를 반환할 것이다.


위의 상황에서 두 프로세스는 서로 선점하는 Resource가 다르므로 동시에 Critical Section 진입이 가능하지만, 서로의 자원을 요구하는 탓에 탈출은 불가능하다. 이 상황을 Deadlock이라고 한다.


Deadlock 이 발생하면 자원의 누수 및 동작의 교착상태가 계속되기 때문에 어플리케이션 또는 시스템에 치명적이며 따라서 문제 해결을 위해 다음과 같이 관리 한다.


- 교착 상태의 예방

(1) Mutual Exclusion 조건 제거

(2) 사용할 때에만 해당 자원을 점유하고 사용하지 않을 때에는 해당 자원을 다른 프로세스가 사용할 수 있도록 양도

(3) 선점 가능한 프로토콜 제작

(4) 자원 접근에 대한 순차적 처리 


- 교착 상태의 회피

 : 자원 요청에 대해 Circular Wait를 방지하기 위한 할당 상태를 검사한다.


- 교착 상태의 무시

 : 확률이 낮은 경우 별도의 처리를 하지 않는다.




 Linux 서버 관리를 하다가 자주 마주치는 것 중 하나가 서버의 포트 및 방화벽 문제라고 할 수 있는데 삽질하면서 알아낸 바를 정리해두었다.


CentOS, Fedora 등의 리눅스에서 포트 방화벽을 확인 하는 방법

- iptables –-list

- iptables -L(리스팅) -v(자세히)


Ubuntu 에서 포트 방화벽을 확인하는 방법

- sudo ufw status


Ubuntu 에서 포트 방화벽을 활성화 / 비활성화 하는 방법

- sudo ufw enable

- sudo ufw disable


CentOS, Fedora 등의 리눅스에서 포트를 추가하는 방법 (WhiteList)

- iptables -I INPUT 1 -p tcp –-dport 80 -j ACCEPT (80 번 Input 포트를 1번으로 추가)

- iptables -I OUTPUT 2 -p tcp –-dport 8080 -j ACCEPT (8080번 Output 포트를 2번으로 추가)


Ubuntu 에서 포트를 추가하는 방법 (WhiteList)

- sudo ufw allow <port>/<optional: protocol> (sudo ufw allow 443/tcp)


CentOS, Fedora 등의 리눅스에서 포트 WhiteList를 제거하는 방법

- iptables -D INPUT 2 (INPUT 2번째 규칙 제거)


Ubuntu 에서 포트 WhiteList를 제거하는 방법

- sudo ufw deny <port>/<optional: protocol>


Iptables 를 이용한 포트포워딩

- iptables -t nat -A PREROUTING -p tcp -m tcp –dport 80 -j REDIRECT –to-ports 8080

- iptables -t filter -A FORWARD -p tcp -m tcp –dport 80 -j ACCEPT


정확히는 삽질한 부분은 클라우드 환경에서 인스턴스의 외부 Security Group 보안설정을 고려하지 않은 채, 인스턴스의 방화벽을 직접 건드린 부분이었으나,

외부 방화벽 제어 로직 역시 다르지 않으므로 기본적인 내용은 익혀두자.


+ Recent posts