1. 4가지 조건이 만족해야 데드락 발생
: Deadlock의 발생은 네트워크의 스레드나 데이터베이스에서나 발생 상황은 같다.
1) mutual exclusion
- 자원이 공유(동시진입)되지 않음
- 동시에 단 한개의 쓰레드(프로세스)만이 자원에 접근 가능함
- 자원이 공유(동시진입)되지 않음
- 동시에 단 한개의 쓰레드(프로세스)만이 자원에 접근 가능함
2) hold and wait
- 한 쓰레드(프로세스)에서 동시에 두개의 자원을 가져야만, 처리가능한 연산
- 두개의 자원을 동시에 필요로 하는 연산처리
3) no preemption
- 일단 한개의 자원을 어떤 쓰레드(프로세스)가 강점하면, 그 누구도 뺏을 방법이 없음
4) circular wait
- 자원에 대해 대기 그래프를 그려보면, 이 그래프에는 cycle이 존재
- 서로 서로 자원을 링크 소유
--------------------------------------------
2. 데드락 발생 시키게 하지 않을려면
1) mutual exclusion
- 자원을 공유하게 만든다 (완전! 재진입되게 만든다)
- 실전에서는 아주 어려운 작업 (운영체제 만드는 수준의...)
2) hold and wait
- 동시에 한개 이상의 자원을 요구하지 못하게 한다.
- 데드락이 될지 모르는 모든 요청에 대해 reject한다.
- 모든 자원에 대한 모든 접근은 동시에 이뤄지게 한다.
- 현재 소유한 자원을 free한 이후에 동시에 다수개 자원을 요청하도록 한다.
3) no preemption
- 자원을 preemtable하게 한다
- 실전에서는 아주 어려운 작업임
- 역시 운영체제 제작하는 수준의 코드가 필요...
4) circular wait
- 자원에 대해 순차적으로 요청하게 만든다.
----------------------------------------------
3. 락을 걸고 조용히 사망한 경우
즉, lock건 쓰레드가 unlock하게 내정된 구조인데, 영원히 unlock하지 않는"에 해당하므로
다음과 같이 해석.
즉, lock건 쓰레드가 unlock하게 내정된 구조인데, 영원히 unlock하지 않는"에 해당하므로
다음과 같이 해석.
1) mutual exclusion
- lock은 해제하기 전에 풀리지 않는다.
이때 아무도 재진입이 불가하다.
- lock은 해제하기 전에 풀리지 않는다.
이때 아무도 재진입이 불가하다.
2) hold and wait
- lock을 걸고 무한히 기다리고 있는 형국이다.
3) no preemption
- 그 어떤 코드도 락을 풀려고 하지 않고 있다.
- 락이 풀리기를 모두 대기하고 있다.
---------------------------------------------------
※ (발생 상황 EX) Multi thread
1) Lock 을 하고 Unlock 하지 않았을 때 무한 대기.
void* ThreadLinkFunction( void* arg )
{
for( int i = 0; i < THREAD_CYCLE; i++ )
{
pthread_mutex_lock( (pthread_mutex_t*)arg );
sleep(1);
//pthread_mutex_unlock( (pthread_mutex_t*)arg );
}
...
}
2) 양쪽 스레드에서 Lock을 잘못 사용할 때.
void* Thread_ALinkFunction( void* arg )
{
for( int i = 0; i < THREAD_CYCLE; i++ )
{
pthread_mutex_lock( &mutex1 );
sleep(1);
pthread_mutex_lock( &mutex2 );
sleep(1);
pthread_mutex_unlock( &mutex2 );
pthread_mutex_unlock( &mutex1 );
}
...
}
void* Thread_BLinkFunction( void* arg )
{
for( int i = 0; i < THREAD_CYCLE; i++ )
{
pthread_mutex_lock( &mutex2 );
sleep(1);
pthread_mutex_lock( &mutex1 );
sleep(1);
pthread_mutex_unlock( &mutex1 );
pthread_mutex_unlock( &mutex2 );
}
...
}
3) 무한 대기 상태나 오랫동안 리소스를 차지 할때
void* ThreadLinkFunction( void* arg )
{
for( int i = 0; i < THREAD_CYCLE; i++ )
{
pthread_mutex_lock( &mutex1 );
while(true) {}
sleep(1);
pthread_mutex_unlock( &mutex1 );
}
...
}
※ (발생 상황 EX) Database
테이블 변경 및 삽입 후 commit으로 트랜잭션을 완료 하지 않을 때.
unique와 무결성을 유지 하기 위해 변경한 데이터 유지를 위해 락이 걸려 있는 상태에서 상대방 테이블에 서로 서로 접근 시 무한 대기 상태.
user_1
SQL> Alter table employees add column email varchar(40);
SQL> Alter table user_2.employees add column email varchar(40);
user_2
SQL> Alter table employees add column job_address varchar(60);
SQL> Alter table user_1.employees add column job_address varchar(60);
---------------------------------------------------
4. Critical Section 내에서 피해야 좋은 코드들
- thread 또는, process가 사망할 가능성이 있는 코드는 피한다.
- 위험한 길은 조심하다가 빠르게 지나가듯이, 빠르게 수행하도록 코드를 잘 보정한다.
- 무한히 다른 것(조건, 입력 등등)을 기다리는 코드는 피한다.
- Lock을 걸때는 아주 간단한 코드에 대해서 걸도록 유의한다.(함수 등을 필할 수 있으면 아주 좋다)
- Lock내에서 사용된 코드는 아주 간결하게 작성한다.
- 혹시, thread 또는 process가 정상 또는 비정상 사망할 경우 소유한 자산(자원)은 반드시 반납하게 작성한다.
- 데이터베이스는 변경 및 수정 완료 후 commit이나 rollback 한다.
출저 : kldp.org/node/36014
'[ Programing ] > Server' 카테고리의 다른 글
이벤트 객체 CreateEvent, SetEvent, ResetEvent, PulseEvent (0) | 2012.12.04 |
---|---|
Shared memory (0) | 2010.07.23 |
메모리 락 (0) | 2010.06.29 |
POSIX 정규 표현식 (0) | 2010.06.29 |
Mutex 설정 (0) | 2010.06.16 |