1.2.7 프로세스 동기화
경쟁 상태
여러 프로세스 또는 스레드에서 하나의 공유자원에 동시에 접근하여 경쟁하는 상태
💡 너무 많은 우유 문제 - 프로세스 동기화가 필요하다!!
- 엄마가 냉장고에 우유 없는 걸 확인
- 엄마 우유 사러감
- 엄마 우유 사고 돌아오는 길에 아빠도 냉장고에 우유 없는 거 확인
- 아빠 우유 사러감
- 우유 2개 됨 -> 의도하지않은 결과
임계 영역
공유 자원에 접근할 수 있고 접근 순서에 따라 결과가 달라지는 코드 영역
* 우유문제에서 냉장고에 우유가 있는지 없는지 판단하고 우유를 추가하는 부분이 이에 해당한다.
☝🏻 임계 영역에서 경쟁상태를 방지하기 위해 프로세스 동기화가 필요하다.
💡 임계 영역에 여러 접근이 동시에 발생하는 것을 방지하는 3가지 방법
- 상호 배제 기법(mutual exclusive)
어떤 프로세스가 임계 영역을 실행 중일 때 다른 프로세스가 접근할 수 없게 한다.(뮤텍스, 세마포어)
"한 방에 한 명만 들어간다" - 진행(progress)
임계 영역을 실행 중인 프로세스가 없을 때 다른 프로세스가 임계 영역을 실행한다.
"방에 아무도 없으면 누군가 적극적으로 들어가야한다" - 한정된 대기(bounded waiting)
임계 영역에 접근을 요청했을 때 무한한 시간을 기다리지 않는다.
"기다리고 있는 사람을 오래 기다리게 하지 않는다"
뮤텍스
뮤텍스는 락(lock)을 가진 프로세스만이 공유 자원에 접근할 수 있게 하는 방법
💡 화장실과 화장실 열쇠가 하나뿐인 식당
- A가 열쇠를 가지고 화장실에 간다.
- B는 열쇠가 없기 때문에 A가 화장실에 갔다가 돌아올 때까지 기다려야한다.
- A가 돌아오면 B는 열쇠를 가지고 화장실에 간다.
여기서,
화장실은 공유 자원을 포함한 임계 영역
열쇠는 락
A와 B는 공유 자원에 접근하려는 프로세스
☝🏻 임계 영역에 접근한 프로세스가 임계영역에 락을 건다고 해서 락킹 매커니즘이라고도 한다.
💡 바쁜 대기
임계 영역에 접근하려고 기다리는 프로세스가 공유자원에 접근할 수 있는 권한을 얻을 때까지 확인하는 과정
* 스핀락 : 바쁜 대기의 한 종류로 락이 풀렸는지 반복문을 돌면서 확인하는 것
세마포어
공유 자원에 접근할 수 있는 프로세스의 수를 정해 접근을 제어한다.
* 뮤텍스와 동일하지만 접근할 수 있는 프로세스가 여러개이다. 즉, 화장실이 3개, 열쇠도 3개임.
☝🏻 공유 자원에 접근한 프로세스가 접근을 해제하면 다른 프로세스에 신호를 보낸다고 해서 시그널링 메커니즘이라고도 한다.
⏬ 동기, 비동기, 블로킹, 넌블로킹 비교
동기 🆚 비동기
여러 작업을 처리할 때,
동기 : 작업 순서를 보장한다.
비동기 : 작업 순서를 보장하지 않는다.
블로킹 🆚 넌블로킹
작업을 수행할 때,
블로킹 : 대기할 수 있다. 작업 순서를 보장하지 않는다
넌블로킹 : 대기없이 수행한다.
1.2.8 교착 상태(deadlock, 데드락) ⭐️⭐️⭐️
2개 이상의 프로세스가 각각 자원을 가지고 있으면서 서로의 자원을 요구하며 기다리는 상태
💡 교착상태가 발생하는 4가지 필요 충분 조건
- 상호배제(mutual exclusion)
하나의 공유 자원에 하나의 프로세스만 접근할 수 있다.
"화장실은 한 번에 한 사람만 사용 가능!" - 점유와 대기(hold and wait)
프로세스가 최소 하나의 자원을 점유하고 있는 상태에서 추가로 다른 프로세스에서 사용중인 자원을 점유하기 위해 대기한다.
"A가 화장실을 쓰고 있으면서, B가 쓰는 드라이기도 달라고 요청" - A는 B가 쓰는 드라이기를, B는 A가 쓰는 화장실을 기다림 - 비선점(non-preemption)
다른 프로세스에 할당된 자원을 뺏을 수 없다
"누군가 화장실을 쓰고 있으면 강제로 문을 열고 들어갈 수 없다" - 환형 대기(circular wait)
프로세스가 자신의 자원을 점유하면서 앞이나 뒤에 있는 프로세스의 자원을 요구한다.
"세사람이 원형으로 서로의 물건을 달라고 요청하면서 기다린다." - 세사람 모두 원하는 물건을 먼저 받아야 내 물건을 줄 수 있음
즉, 프로세스는 다음 자원을 받기 전까지 자신이 가진 자원을 반환하지 않는다.
☝🏻 교착상태를 막으려면 이 4가지 필요 충분 조건중에 한 가지를 제거하면 된다.
- 상호배제 부정
여러 프로세스가 동시에 하나의 공유 자원을 사용할 수 있도록 한다.
"화장실 안에 🚽를 여러개 만들어서 여러 명이 사용할 수 있도록" - 점유와 대기 부정
프로세스가 실행되기 전에 필요한 모든 자원을 할당 -> 프로세스 대기를 없앤다
프로세스가 자원을 점유하지 않은 상태에서만 자원을 요구
"A에게 처음부터 화장실과 드라이기를 준다" or "A가 화장실을 사용하지 않을 때만 드라이기를 요구한다" - 비선점 부정
자원을 점유한 프로세스가 다른 자원을 요구할 때 점유하고 있는 자원을 반납한다.
"A가 화장실을 쓰고 있으면서 드라이기를 요구한다면, A는 화장실을 먼저 비워야 드라이기를 요청할 수 있다" - 환형 대기 부정
자원을 선형 순서로 정렬해 고유 번호를 할당한다. 그리고 각 프로세스에서 요구할 수 있는 번호의 방향을 정해서 한쪽 방향으로만 자원을 요구한다.
"화장실(1번), 드라이기(2번) : 1번을 먼저 요청해야만 2번을 요청할 수 있다."
1.2.9 스레드 안전
스레드 안전이란 하나의 변수, 함수, 객체에 스레드 여러개가 동시에 접근해도 문제가 없음을 의미한다.
* 스레드 안전하지 않은 경우 스레드끼리 데이터 값을 덮어쓰기가 일어날 수 있다.
💡 스레드 안전을 위한 조건
- 상호배제(mutual exclusion)
뮤텍스 또는 세마포어와 같은 상호배제 기법을 사용해 접근을 통제해야한다.
"화장실은 한 번에 한 명만 사용하도록 잠금장치를 건다" - 원자 연산(atomic operation)
공유 자원에 접근할 때 원자 연산(연산했다, 연산 안했다)을 이용한다.
"100원 인출 버튼을 눌렀을 때 100원이 인출될 때까지 다른 사람이 개입 못함" - 재진입성(reentrancy)
특정 함수를 하나의 스레드에서 실행 중일 때 다른 스레드가 해당 함수를 실행해도 각 스레드에 올바른 결과가 나올 수 있게 한다.
"한 개의 시험 문제를 각자 자신의 노트에 푼다" -> 충돌 방지 - 스레드 지역 저장소(thread local storage)
각 스레드에서만 접근할 수 있는 저장소를 사용해서 공유되는 자원을 줄인다.
"필요한 물건을 자기 서랍에 보관하고 사용"
1.2.10 IPC
IPC는 프로세스가 자원을 공유하는 방식이다.
* 프로세스는 고유한 메모리 영역을 가지기 때문에 프로세스간에 자원을 공유해야 할 때가 있다.
💡 IPC 종류
- 공유 메모리(shared memory)
프로세스간 공유 가능한 메모리를 구성해 자원을 공유한다.
여러 프로세스에서 접근할 때 동기화 문제가 발생할 수 있다.
"같은 노트를 공유해서 데이터를 쓰고 읽는다" - 소켓(socket)
네트워크 소켓을 이용하는 프로세스 간 통신으로, 외부 시스템과도 이용할 수 있다.
클라이언트 <-> 서버 구조로 자원을 주고받는다.
"클라이언트가 편지를 보내고 서버가 우체통 역할을 한다." - 세마포어(semaphore)
접근하는 프로세스를 제어 -> 화장실 키 만들어
"화장실 키 만들어" - 파이프(pipe)
FIFO형태의 메모리인 파이프를 이용해서 프로세스 간 자원을 공유
단방향 통신만 지원하므로 읽기 또는 쓰기 중 하나만 할 수 있음. 양방향 통신하려면 읽기파이프 쓰기파이프 생성해야함
"한 쪽 프로세스는 데이터를 읽기만하고, 한 쪽은 쓰기만 함" - 단방향 통신
"A는 1번 벨트에 요청을 보내고 B는 2번 벨트에 요청을 보냄, A는 2번 벨트에서 요청을 받고 B는 1번 벨트에서 요청을 받음" - 양방향 통신 - 메시지 큐(message queue)
FIFO형태의 큐 자료구조를 사용해서 프로세스 간 메시지를 주고받는다. - 우선순위로 각자 맞게끔 가져가게 함
"여러 사람이 편지(메시지)를 우체통에 넣고 필요한 사람이 순서대로 편지를 가져감"
1.2.11 좀비 프로세스와 고아 프로세스
💡 좀비 프로세스
자식 프로세스가 종료되었는데 부모 프로세스가 자식 프로세스의 종료 상태를 회수하지 않았을 경우 남겨진 자식 프로세스
- 자식 프로세스가 종료 -> 부모에 SIGCHLD 시그널 보냄
- 부모 프로세스는 wait() 함수(시스템 콜)을 호출해 자식 프로세스의 상태 정보를 받고 자원을 회수
- 이때, 자원 회수에 실패하면 자녀는 좀비가 됨....
좀비 프로세스가 쌓이면 자원이 낭비됨
💡 고아 프로세스
자식 프로세스보다 부모 프로세스가 먼저 종료되는 경우 -> 종료했을 때 자원을 회수해줄 부모가 없음
이럴 때 자식 프로세스의 부모 PID를 1(init프로세스)로 바꾸고 종료됐을 때 init프로세스가 고아의 자원을 회수해준다.
-> 좀비 프로세스 방지
'[ STUDY ] > CS' 카테고리의 다른 글
[ 운영체제 ] 가상 메모리 - 요구 페이징, 스레싱 (0) | 2024.11.11 |
---|---|
[ 운영체제 ] 메모리 관리 전략 - 페이징, 세그먼테이션 (0) | 2024.11.11 |
[ 운영체제 ] 스케줄링 (0) | 2024.11.11 |
[ 운영체제 ] 프로세스 1️⃣ - 프로세스, 스레드, 콘텍스트 스위칭, PCB ··· (0) | 2024.11.11 |
[ 운영체제 ] 운영체제 (1) | 2024.11.10 |