Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Swift] 동시성 프로그래밍의 문제점 #10

Closed
seungchan2 opened this issue May 3, 2022 · 0 comments
Closed

[Swift] 동시성 프로그래밍의 문제점 #10

seungchan2 opened this issue May 3, 2022 · 0 comments
Assignees
Labels

Comments

@seungchan2
Copy link
Owner

seungchan2 commented May 3, 2022

Thread-safe 하지 않음

멀티 쓰레드의 환경에서, 같은 시점에 여러개의 쓰레드에서 하나의 메모리에 동시접근 하는 문제

멀티 쓰레드 환경(Concurrency 프로그래밍)에서 발생할 수 있는 문제

위의 그림에 대해 간단히 설명을 하자면 Thread2, Thread3이 존재하는데

Thread2는 seungchan.age 의 값을 5로 바꾸는 과정이다. (쓰기)

Thread3은 seungchan.age를 print문에 담아 출력을 하는 과정이다. (읽기)

하지만 여기서 중요한 것은 같은 시점에 동시에 접근을 했다는 것인데 Thread2와 Thread3 둘 중에 우선순

위가 정해져 있지 않다면 쓰기를 먼저 할 것 인지 읽기를 먼저 할 것 인지 상당히 애매한 상황이 될 것이다.

하나의 메모리에 동시에 접근하는 상황을 Thread-safe하지 않음 / 경쟁상황, Race Condition라고 한다.

어떻게 해결?

이를 해결하기 위해서 정말 많은 방법이 있는데 메모리에 하나의 Thread에서 접근할 수 있도록 Lock을 걸

어 Thread-Safe 한 상태를 만들 수 있고, 동시큐에서 직렬큐로 보내는 방법이 있다.

교착상태 (DeadLock)

멀티 쓰레드의 환경에서, 배타적인 메모리사용으로 일이 진행이 안되는 문제

2개 이상의 쓰레드가 서로 배타적인 메모리의 사용으로 인해 (서로 잠그고 점유하려고 하면서) 메서드의 작업이 종료도 못하고 일의 진행이 멈춰 버리는 상태
Swift-8 2

위의 그림에 대해 간단히 설명을 하자면 Thread2, Thread3이 존재하는데

같은 시점에 동시에 접근을 하게 된다. 하지만 서로 점유하려고 하는 특징 때문에 메서드의 작업

이 종료되지 않고 일의 진행이 멈춰버린다.

다른 예시를 들면 나와 태현이가 엽떡을 먹으려고 배달을 시켰는데 이제 젓가락이 한 세트만 온 경우를 생각해보자.

둘이 너무 배고파서 젓가락을 1개씩 써서 먹을 수 있겠지만 1개로는 먹기가 싫고 먼저 서로 먹고 싶어하기 때문에 계속해서 눈치만 보고 있다 ..

이것이 교착상태, DeadLock의 간단한 예시이다.

그렇다면 동시성 프로그래밍의 문제점을 어떻게 해결할 수 있을까?

앞서 말했듯이 동시큐에서 직렬큐로 보내는 방법이 있다

코드 예시

var array = [String]()

for i in 1...20 {
    DispatchQueue.global().async {
        print("\(i)")
        array.append("\(i)")   
    }
}

위의 코드를 실행시키면 결과는 어떻게 될까?

async하기 때문에 배열에 랜덤하게 담기겠지? 라고 생각할 것이다.

스크린샷 2022-05-04 오후 2 14 07

하지만 array의 값을 잘 살펴본다면 없는 것들이 있다....

Swift-9 2
이게 위의 코드를 가시적으로 나타낸 그림이다.

각 쓰레드에서 배열에 원소를 담고 있는 과정이다.

결론부터 말하자면 Thread-safe하지 않은 상태이다.

같은 시점에서 멀티 쓰레드 상황에서 우선 순위가 정해져 있지 않으므로 어떤 것은 배열에 담기고 어떤 것은 담기지 않을 것이다.

그렇다면 해결할 수 있는 방안으로는 직렬큐로 보내는 방법이다.

var array = [String]()

let serialQueue = DispatchQueue(label: "serial")

for i in 1...20 {
    DispatchQueue.global().async {
        print("\(i)")
        serialQueue.async {        
            array.append("\(i)")
        }
    }
}

DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
    print(array)
}

해당 코드를 실행시킨다면
스크린샷 2022-05-04 오후 2 27 44
아래와 같이 1...20이 모두 배열에 담겨 출력된다.

Swift-10
직렬큐에 보내줌으로 순차적으로 배열에 담길 수 있게 해준다.

결론

동시성 프로그래밍의 문제점으로 Thread-safe 하지 않음 / 교착상태가 있고

이를 해결하기 위해서 Thread에 Lock을 걸어주거나 직렬큐로 보내서 해결하는 방법이 있다.

@seungchan2 seungchan2 self-assigned this May 3, 2022
@seungchan2 seungchan2 changed the title [Swift] GCD [Swift] 동시성 프로그래밍의 문제점 May 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant