thread safe

hankyulee·2023년 3월 12일
0

결론: thread safe의 정의는 공용변수 나 객체에 한번에 하나의 스레드만 접근하면 thread safe. print에 이상한 값이 나오냐 문제가 아님.
객체에 여러 스레드가 접근할 가능성이 있으면 thread safe한 처리가 필요하다.

예를들어 for문안에 global queue로 task를 async 하게 보내는 코드를 5번 반복한다고 하자. 이때 그 코드 안에는 하나의 Person 데이터타입에 접근하여 2초뒤에는 앞글자를 변화시키고 5초 뒤에는 뒤글자를 변화시키면, 5개의 여러스레드에서 작업될때 예상치못한 결과낳는다. 이게 race condition.

Developers don't typically access GCD directly but instead use Dispatch Queues to manage their tasks in a concurrent and asynchronous manner.

멀티스레드 환경에서 공용변수 접근시 race condition이나 동시성 문제가 발생할 수 있다.
concurrentQueue에 read 작업은 일반적인 task로 넣고, write 작업을 barrier task로 넣는 식으로 Dispatch barrier를 응용 가능. 왜냐하면 읽기는 사실 여러개의 스레드에서 접근해도 상관없잖아여?? 문제가 되는건 쓰기를 통해 바뀐는 경우
출처: https://sujinnaljin.medium.com/ios-%EC%B0%A8%EA%B7%BC%EC%B0%A8%EA%B7%BC-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-gcd-13-723d33e157e

nslock을 이용해 여러스레드를 for문에서 돌리더라도 수정하거나 get할때 lock, unlock하여 하나의 스레드에서만 접근할 수 있도록 가능

async가 sync 보다 느리게 처리하는 성능 가짐.
출처: https://ios-development.tistory.com/1083

barrier flag를 이용.

Non-blocking: Unlike NSLock, DispatchSemaphore is a non-blocking mechanism. If a thread tries to acquire a semaphore that is currently held by another thread, it will be put into a waiting state until the semaphore becomes available. However, the waiting thread is not blocked and can continue to execute other tasks in the meantime. This can lead to better performance and resource utilization in situations where locking operations take a long time to complete or if there are many threads waiting to acquire the lock. 여러개 필요없으면 nslock

dispatch semaphore:
some locking mechanisms provide a way for threads to try to acquire a lock without waiting for other threads to release it. These are known as non-blocking locking mechanisms.

아래와 같이 dictionary에서 동일한 key에 접근하는 것이 아니더라도 race condition에 해당한다.

barrier를 사용할 경우 read일때는 async, 쓰기일때는
barrier사용시 write를 async를 보내는 이유는 어차피 barrier로 하나의 스레드만 작업하게 되기때문.

sync를 사용할 경우, 예를들어 write와 read가 하나로 묶인 task라면 이를 여러개의 스레드에서 시리얼 큐에 task를 넘기고 하나의 스레드에서 task를 처리하니 wirte, read가 순차적으로 일어난다 즉 엄격하다.
barrier을 사용할 경우, write와 read가 묶여있고, write할때 barrier flag를 주고 read할때는 sync로 줄때(sync로 주는 이유는 write한 것에 대해 최대한 읽기 위해서), write하는 동안 barrier로서 다른 스레드를 막는데, read할때 다른 write가 다시 다시 스레드들을 막으면서 read하는 타이밍이 섞인다. 즉 엄격하지 않다. 그러나 concurrent이기때문에 효율적이라 할 수 있다.

0개의 댓글