0Pricing
Swift Academy · 강의

생산자/소비자, 파이프라인, 시간 초과

간단한 생산자/소비자 를 만들고, AsyncSequence로 파이프라인 을 조합하며, 절전 작업과 경쟁시키는 방식으로 시간 초과 를 구현합니다.

생산자/소비자, 파이프라인, 시간 초과은(는) CoddyKit의 무료 Swift Academy 강의입니다. 이것은 3개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Swift Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Swift Academy 강의에는 총 3개의 강의가 포함되어 있습니다.

만들 내용

이 레슨에서는 세 가지 패턴을 보여 드립니다.

  • AsyncStream을 사용하는 생산자/소비자 패턴
  • AsyncSequence 변환을 사용하는 파이프라인
  • 작업을 협력적으로 경쟁시켜 구현하는 시간 초과 처리

기본 생산자/소비자

AsyncStream은 푸시 방식 생산자와 풀 기반 for await 소비를 연결합니다.

// Producer pushes values; consumer iterates them asynchronously.
func makeNumbers(count: Int) -> AsyncStream<Int> {
    AsyncStream { continuation in
        Task {
            for i in 1...count {
                continuation.yield(i)
                try? await Task.sleep(nanoseconds: 40_000_000) // ~40ms
            }
            continuation.finish()
        }
    }
}

Task {
    let stream = makeNumbers(count: 5)
    for await n in stream {
        print("consume:", n)
    }
    print("done") // after finish()
}

백프레셔 정책

백프레셔를 관리하려면 bufferingPolicy를 선택하십시오. 오래된 항목 삭제, 최신 항목 삭제 또는 작은 스트림을 위한 무제한 버퍼를 사용할 수 있습니다.

// Use a limited buffering policy to avoid memory spikes.
func makeBufferedNumbers(limit: Int) -> AsyncStream<Int> {
    AsyncStream(bufferingPolicy: .bufferingOldest(limit)) { cont in
        Task {
            for i in 1...20 {
                cont.yield(i)
                // Producer is fast; buffer prevents unbounded growth
            }
            cont.finish()
        }
    }
}

Task {
    let s = makeBufferedNumbers(limit: 5)
    for await n in s {
        // Simulate a slow consumer
        try? await Task.sleep(nanoseconds: 60_000_000)
        print("got:", n)
    }
}

AsyncSequence를 사용한 파이프라인

AsyncSequence는 익숙한 연산자(map, filter, reduce)를 지원하므로 스트리밍 파이프라인을 명확하게 구성할 수 있습니다.

// Compose a pipeline: map -> filter -> reduce over an AsyncSequence.
func numbers(_ n: Int) -> AsyncStream<Int> {
    AsyncStream { cont in
        Task {
            for i in 1...n { cont.yield(i) }
            cont.finish()
        }
    }
}

Task {
    let evensSquaredSum = await numbers(10)
        .map { $0 * $0 }
        .filter { $0.isMultiple(of: 2) }
        .reduce(0, +)
    print("sum:", evensSquaredSum) // 220 (4+16+36+64+100)
}

병렬 단계

CPU 연산 중심의 변환에는 파이프라인 내부에서 task 그룹을 사용한 다음, 원하는 순서로 결과를 다시 병합하십시오.

// Fan-out/fan-in: process items concurrently, then merge.
// Here we use a task group to transform elements in parallel.
func parallelUppercased(_ input: [String]) async -> [String] {
    await withTaskGroup(of: String.self) { group in
        for s in input {
            group.addTask {
                try? await Task.sleep(nanoseconds: 30_000_000)
                return s.uppercased()
            }
        }
        return await group.reduce(into: [String]()) { $0.append($1) }
    }
}

Task {
    let out = await parallelUppercased(["a","bb","ccc"])
    print(out) // ["A","BB","CCC"]
}

시간 초과 도우미

작업을 sleep task와 경쟁시켜 시간 초과를 구현하십시오. 작업을 절약하려면 진 작업을 cancel하십시오.

enum TimeoutError: Error { case timedOut }

func withTimeout<T>(
    seconds: Double,
    operation: @escaping () async throws -> T
) async throws -> T {
    try await withThrowingTaskGroup(of: T.self) { group in
        // Child 1: actual work
        group.addTask { try await operation() }
        // Child 2: the timer
        group.addTask {
            try await Task.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
            throw TimeoutError.timedOut
        }
        // First child to finish wins; cancel the rest
        let result = try await group.next()!
        group.cancelAll()
        return result
    }
}

// Demo
func slowFetch() async throws -> String {
    try await Task.sleep(nanoseconds: 300_000_000) // 300ms
    return "OK"
}

Task {
    do {
        let v = try await withTimeout(seconds: 0.1) { try await slowFetch() }
        print("value:", v)
    } catch {
        print("timeout:", error) // expected
    }
}

시간 초과 패턴(경쟁)

간단 확인: 시간 초과를 추가하는 좋은 방법은 무엇인가요?

요약

요약:

  • 생산자/소비자 패턴에는 AsyncStream을 사용하십시오.
  • map/filter/reduce를 사용해 AsyncSequence 파이프라인을 구성하십시오.
  • 작업을 경쟁시키고 진 작업을 cancel하여 시간 초과를 구현하십시오.

자주 묻는 질문

“생산자/소비자, 파이프라인, 시간 초과” 강의는 무료인가요?

네 — “생산자/소비자, 파이프라인, 시간 초과” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Swift Academy 강의 전체를 잠금 해제할 수 있습니다. Swift Academy 강의에는 총 3개의 강의가 포함되어 있습니다.

“생산자/소비자, 파이프라인, 시간 초과”에서 뭘 배우나요?

간단한 생산자/소비자 를 만들고, AsyncSequence로 파이프라인 을 조합하며, 절전 작업과 경쟁시키는 방식으로 시간 초과 를 구현합니다. 브라우저에서 직접 실행하는 실습 코드로 Swift Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Swift Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Swift Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 3개 중 1번째 강의입니다.

“생산자/소비자, 파이프라인, 시간 초과” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Swift Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Swift Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 생산자/소비자, 파이프라인, 시간 초과
  2. 기존 콜백/Combine을 async/await로 연결하기
  3. 비동기 코드 테스트(XCTest)
← Swift Academy(으)로 돌아가기