식사하는 철학자들 철학자들은 배고프면 식사를 하고 식사를 마쳐서 배가 부르면 사고를 한다. 철학자들 양 옆에는 포크가 놓여져 있고 식사를 하기 위해선 양 옆의 두 개의 포크를 이용해야 한다. 철학자들이 식사를 하는 방법은 다음과 같다. -> 왼쪽 포크가 사용 가능해질 때까지 대기한다. 만약 사용 가능하다면 집어든다 -> 오른쪽 포크가 사용 가능해질 때까지 대기한다. 만약 사용 가능하다면 집어든다. -> 양쪽의 포크를 잡으면 일정 시간만큼 식사를 한다. -> 오른쪽 포크를 내려놓는다. -> 왼쪽 포크를 내려놓는다. -> 다시 1번으로 돌아간다. 식사를 하기 위해 어떤 포크를 집어 든다면 그 포크는 다른 철학자가 접근하지 못한다. - 포크 = 임계 자원(상호 배제를 만족해야 함) 위의 조건을 지키면서 작업을..
Deadlock semaphore는 한가지 임계 자원이 아닌 여러 임계 자원에 대한 상태를 나태낼 수 있고 아래와 같이 P0, P1가 S, Q라는 임계 자원을 동시에 접근했다고 하면, 첫 S와 Q는 각각 1개의 프로세스가 사용할 수 있다고 가정했을 때 P0와 첫줄의 wait함수를 호출하면 S의 count가 1에서 0으로 바뀐다. 이 때 만약 스케쥴러가 P1을 할당하면 Q도 마찬가지로 0으로 바뀔 것이다. 하지만 또다시 스케쥴러가 P0를 호출한다면 두번째 줄의 wait함수를 호출했을 때 Q가 0이므로 대기 상태로 들어가고 다시 P1이 실행되면 P1도 마찬가지로 S가 0이므로 대기 상태로 들어갈 것이다. 이렇게 두 프로세스가 어느 한쪽도 수행되지 못하는 Deadloack이 발생된다. Deadlock의 특징 ..
조건 변수를 활용하여 여러 쓰레드의 순서를 동기화 할 수 있었는데, 이는 뮤텍스와 같이 사용되어 조금은 복잡한 코드였다. 세마포어를 잘 활용하면 조건 동기화를 동시에 해결할 수 있다. 원래의 조건 동기화 코드는 조건 변수를 사용하기 전과 후에 상호 배제를 위해서 mutex를 사용했지만 세마포어는 그 자체로 상호 배제를 만족하므로 sem_t s; void * child (void *args) { printf(“child\n”); sem_post(&s); return NULL; } int main(int argc, char *argv[]) { sem_init(&s, 0, 0); printf(“parent: begin\n”); pthread_t c; pthread_create(c, NULL, child, NU..
condition Synchronization 만약 쓰레드 A가 쓰레드 B, C의 작업이 다 끝나고 수행되어야 하는, 의존성이 존재하는 쓰레드라고 했을 때 B와 C의 작업이 끝날때 까지 A를 대기시키고, B와 C의 작업이 끝났다는 조건이 충족되면 A가 실행되어야 할 것이다. [Thread-1] int main(int argc, char *argv[]) { pthread_t c; printf("parent: begin\n"); pthread_create(&c, NULL, child, NULL); while (done == 0) { } printf("parent: end\n"); return 0; } [Thread-2] void * child (void *arg) { printf("child\n"); don..
Semaphore 공유된 자원의 데이터 혹은 임계영역(Critical Section) 등에 여러 Process 혹은 Thread가 접근하는 것을 막아줌 (동기화 대상이 하나 이상) semaphore는 특정 임계 구역에 접근할 수 있는 프로세스의 수를 나타내는 변수이다. - mutex와 달리 대기할 프로세스를 레디 큐에 넣는 것이 아니라 block시켜서 스케쥴러의 대상에서 빠지게 만든다. busy wating할 필요가 없어서 cpu 사용효율을 높일 수 있다. 이러한 프로세스의 상태 변경을 sleep - awake 라고 부른다 - semaphore 변수가 0과 1만 사용되면 mutex와 같은 방식의 동기화를 수행한다. 이를 binary semaphore라고 한다. - 0과 1이 아닌 다른 범위의 정수를 se..
경쟁 상태(Race Condition) 다수의 프로세스나 스레드가 공유 자원을 동시에 읽거나 쓰려고 하는 상태를 의미한다. 최종 수행 결과는 프로세스들의 수행 순서에 따라 달라진다. 싱글프로세서에서 race condition 싱글 프로세서에서 stack1에 쓰레드1, stack2에 쓰레드2가 진행된다고 했을 때 아래 그림의 전역변수 counter에 접근한다고 한다면 counter는 2가 되어야 할 것이다. 아키텍쳐마다 다르지만 counter++명령이 밑의 3개의 작업으로 이루어진다고 했을 때 쓰레드 A에서 전역변수 counter를 로드한 시점에 스케쥴러에 의해 쓰레드 B가 실행되고 counter++작업을 마쳤다. 다시 쓰레드 A로 돌아가서 작업을 할때는 이미 load된 counter값인 0에 1을 더하고..
멀티 프로세서의 발전 - 처리기가 늘어남에 따라 어떤 프로세스에 어떤 처리기를 할당할지 복잡해짐 주요 이슈 cache affinity (친화력) - 특정 프로세서에서 실행된 프로세스는 가능하다면 계속 동일한 프로세서에 할당함 Concurrency (병행성) 여러 프로세서에 프로세스를 할당하기 위해 레디큐(싱글 큐라고 가정)에 동시 접근하여 프로세스를 불러올 때 생기는 문제를 해결 Shared data를 이용할 때 생기는 문제 -> race condition 공유자원에 대해서 한번에 한번씩 접근하게 하는 기법 -> mutual exclusion (ex: 동기화, 데드락) SQMS(single-queue multiprocessor scheduling) 각 cpu가 단순히 전역적인 싱글큐에서 프로세스를 선택하..
예외 오동작이나 결과에 악영향을 미칠 수 있는 실행 중 발생한 오류 • 정수를 0으로 나누는 경우 • 배열보다 큰 인덱스로 배열의 원소를 접근하는 경우 • 존재하지 않는 파일을 읽으려고 하는 경우 • 정수 입력을 기다리는 코드가 실행되고 있을 때, 문자가 입력된 경우 자바에서 예외 처리 가능 • 예외 발생 → 자바 플랫폼 인지 → 응용프로그램에 전달 • 응용프로그램이 예외를 처리하지 않으면, 응용프로그램 강제 종료 예외 처리 • 예외가 발생할 때 대응하는 프로그램 코드 - try-catch-finally문 사용 try { 예외가 발생할 가능성이 있는 실행문(try 블록) } catch (처리할 예외 타입 선언) { 예외 처리문(catch 블록) } finally { 예외 발생 여부와 상관없이 무조건 실행..