#Atomicity Violations
원자성 위반(Atomicity Violations)은 적절한 잠금 규칙을 준수하는 경우에도 발생할 수 있는 동시성 (concurrency) 버그 유형이다(공유 데이터에 액세스하거나 업데이트하는 동안 잠금이 일관되게 유지되는 경우). 보통 Atomic이어야 하는 업데이트가 결합될 때 동일한 잠금의 보호 하에 수행되지 않는 경우 발생한다.
원자성 위반 발생 가능 패턴들:
보호용 잠금 장치 획득 (a)
공유 상태에서 정보를 추출 (b)
잠금 해제 보호 (c)
정보를 기반으로 한 행동에 대한 약속 (d)
S'를 보호하는 잠금 장치 획득 (e)
저장된 정보를 기반으로 한 공유 상태 S'에 대한 조치 (f)
S'를 보호하는 잠금 해제 (g)
공유 상태로 업데이트되어 b)에서 얻은 정보가 f)에서 최신 정보가 아닐 경우 실패한다. (S는 S'와 같을 수 있다).
#Atomicity Violation Example
char *p = ….; /* shared variable */
pthread_mutex_t lp ; /* protects ‘p’ */
….
int getplen() {
pthread_mutex_lock (&lp);
int len = strlen(p);
pthread_mutex_unlock (&lp);
return len;
}
…
int nchars = getplen(); // obtain length (safe by itself)
char *copy = malloc(nchars + 1); // commit to allocate memory
pthread_mutex_lock (&lp);
strcpy(copy, p); // copy now possibly out-of-date version
pthread_mutex_unlock (&lp);
#Atomicity Violation Example 2
public synchronized StringBuffer append(StringBuffer sb) {
// note: StringBuffer.length() is synchronized
int len = sb.length(); //length 획득
int newcount = count + len;
if (newcount > value.length)
expandCapacity (newcount);
// StringBuffer.getChars() is synchronized
sb.getChars(0, len, value, count ); //length가 바뀌었을 시, StringIndexOutOfBoundsException
count = newcount;
return this;
}
#Atomicity Violation Example 3
pthread_mutex_lock (&worker->lock); // protects worker queue
....
struct listelem *e = list_pop_front (&worker->queue); // grab task from worker queue
struct future *f = list_entry (e, struct future, elem);
pthread_mutex_lock (&f->lock); // lock task to update state
f->state = RUNNING; // mark as running
// run task
// somewhere in future_get()....
// lock protects state
pthread_mutex_lock (&future->lock);
if (future->state == NEW) {
// lock containing list
pthread_mutex_lock (&future->owner->lock);
list_remove (&future->elem);
pthread_mutex_unlock (&future->owner->lock);
f->state = RUNNING;
// run task
}
첫 번째 코드 부분: 작업자가 대기열을 잠그고 작업을 제거하고 실행을 커밋한다.
두 번째 코드 부분: 참여자가 새 작업을 보고, 작업을 실행하도록 커밋하고, 대기열에서 제거한다.
작업이 두 번 실행된다
원자성 요구 사항: 작업 상태를 변경하고 작업 대기열에 있는 작업을 제거해야 한다.
#교착 상태를 피하면서 2개의 잠금을 반대 순서로 획득하는 방법
A.lock()
.… find B
B.lock()
// holding A & B
retry:
B.lock()
…. find A
if (!A.trylock())
{ B.unlock(); goto retry; }
// holding A & B
#MySql Atomicity Violation
#Typical Atomicity Violation
'Computer Science > Computer Systems' 카테고리의 다른 글
[Lecture 14] 멀티쓰레딩 VIII - Atomic Variables and Operations (0) | 2022.10.19 |
---|---|
[Lecture 13] 멀티쓰레딩 VII - Performance (0) | 2022.10.19 |
[Lecture 11] 멀티쓰레딩 V - Deadlock (0) | 2022.10.19 |
[Lecture 10] 멀티쓰레딩 IV - Condition Variables & Monitors (1) | 2022.10.09 |
[Lecture 8] 멀티쓰레딩 II - Basic Locking / Managing Shared State (0) | 2022.10.08 |