What is the Sendable protocol in Swift | Swift 동시성 #11

Sung Daegyu·2024년 3월 4일
post-thumbnail

Swift: What is the Sendable protocol in Swift | Swift Concurrency #11

Sendable이란?

  • Actor는 Thread safe로 설계된 class와 같다. 따라서 Actor 내의 모든 메소드는 비동기로 진행되며 thread safe하다.

그렇다면 Actor내의 모든 코드는 thread safe 할까?

  • NO!
  • Actor에서 외부로 참조하는 코드(메소드의 인자)는 thread safe 하지 않을 수 있다.
  • 예) Actor내의 메소드의 인자가 class이고, 이 class가 메소드 진행중에 여러 thread에서 참조된다면 어떻게 될까?
    actor CurrentUserManager {
      func updateDatabase(userInfo: MyUserInfo) {
        // 여러 thread에서 userInfo를 참조하게 되는 코드
    		// 이 경우 actor 내에서도 data race가 발생할 수 있다.
      }
    }
    
    class MyUserInfo {
      var name: String
    }
    
    → Data race가 발생하게 된다!
    → actor 외부에서 thread safe를 보장하는 코드를 작성할 수는 없을까?
    Sendable Protocol을 사용하자

Sendable 사용방법

  1. Value type

    value type의 경우 concurrency에서 값의 복사가 이루어지기 때문에 data race가 발생하지 않으므로, 기본적로 Sendable이다. 따라서, 옆에 그냥 붙여주면 된다.

    struct MyUserInfo: Sendable {
      let name: String
    }

    다만, struct 내의 모든 구성이 value type이거나, sendable을 준수해야 한다.

    다음의 경우에는 Sendable을 붙일 수 없다.

    struct MyUserInfo: ~~Sendable~~ {
      let name: String
    	var myClass: MyClass // NOT Sendable
    }
  2. Reference type (Class)

    class의 경우 sendable을 사용하려면

    1. 변수 var가 없어야 한다.
    2. final이어야 한다.
    3. 상위 클래스가 없어야 한다.
    final class MyClassUserInfo: Sendable {
      let name: String
      
      init(name: String) {
        self.name = name
    	}
    }

    굳이 var를 사용하고 싶다면, @unchecked 키워드를 통해 컴파일러를 무시하고 Sendable 하게 구현할 수 있다.

    대신, 이 경우에는 손수 actor를 구현했던 것처럼 직접 lock을 만들어서 thread safty를 보장해야 한다.

    → 매우 추천하지 않는다.

    final class MyClassUserInfo: @unchecked Sendable {
      private var name: String
      let lock = DispatchQueue(label: "com.MyApp.MyClassUSerInfo")
    
    
      init(name: String) {
        self.name = name
      }
      
      func updateName(name: String) {
      	queue.async {
          self.name = name
        }
      }
    }

참고

https://www.youtube.com/watch?v=wSmTbtOwgbE&list=PLwvDm4Vfkdphr2Dl4sY4rS9PLzPdyi8PM&index=12

profile
대규의 개발로그

0개의 댓글