// Five Channel Operators — Why ch <- and <- ch matter // // 기존: ChSend(ch, val) / ChReceive(ch) — 함수 호출 // 신규: ch <- val / <- ch — 연산자 // // 연산자의 장점: // 1. 짧다: ch <- val vs ChSend(ch, val) // 2. 읽기 쉽다: 화살표 방향 = 데이터 흐름 // 3. WATCH와 자연스럽게 결합 // ==================================================== // 예제 1: 생산자-소비자 (Worker Pool) // ==================================================== PROCEDURE Main() LOCAL chJobs, chResults LOCAL i, nSum, nResult ? "=== Producer-Consumer Pool ===" chJobs := Channel() chResults := Channel() // Worker 3개 가동 SPAWN {|| Worker(chJobs, chResults) } SPAWN {|| Worker(chJobs, chResults) } SPAWN {|| Worker(chJobs, chResults) } // 작업 10개 전송 SPAWN {|| Producer(chJobs, 10) } // 결과 수집 nSum := 0 FOR i := 1 TO 10 nResult := <- chResults // 결과 수신 nSum += nResult ?? Str(nResult, 5) NEXT ? ? "Total:", nSum ? // ==================================================== // 예제 2: WATCH — 먼저 온 채널 선택 // ==================================================== ? "=== Race: Fastest Server ===" TestRace() ? // ==================================================== // 예제 3: Pipeline (단계별 처리) // ==================================================== ? "=== Pipeline: x → x*2 → x+10 ===" TestPipeline() ? ? "Done." RETURN // Worker: 채널에서 받아 제곱 후 전송 FUNCTION Worker(chIn, chOut) LOCAL nJob nJob := <- chIn // ← 작업 수신 chOut <- nJob * nJob // ← 결과 전송 RETURN NIL // Producer: 숫자 n개를 채널로 전송 FUNCTION Producer(ch, nCount) LOCAL i FOR i := 1 TO nCount ch <- i // ← 전송 NEXT RETURN NIL // Race: 여러 채널 중 먼저 도착한 것 선택 PROCEDURE TestRace() LOCAL chA, chB, chTimeout, cResult chA := Channel() chB := Channel() chTimeout := Channel() SPAWN {|| DelayAndSend(0.1, chA, "Server A (100ms)") } SPAWN {|| DelayAndSend(0.5, chB, "Server B (500ms)") } SPAWN {|| DelayAndSend(1.0, chTimeout, "TIMEOUT") } WATCH CASE cResult := <- chA ? " Winner:", cResult CASE cResult := <- chB ? " Winner:", cResult CASE <- chTimeout ? " TIMEOUT!" END WATCH RETURN // Pipeline: Stage1 → Stage2 → 출력 PROCEDURE TestPipeline() LOCAL chStage1, chStage2 LOCAL i, nVal chStage1 := Channel() chStage2 := Channel() // Stage 1: 숫자 생성 SPAWN {|| PipeGenerate(chStage1, 5) } // Stage 2: 2배로 변환 SPAWN {|| PipeDouble(chStage1, chStage2, 5) } // Stage 3: 결과 출력 FOR i := 1 TO 5 nVal := <- chStage2 // Stage2 결과 수신 ? " Input:", i, " Output:", nVal NEXT RETURN FUNCTION PipeGenerate(ch, n) LOCAL i FOR i := 1 TO n ch <- i // 숫자 전송 NEXT RETURN NIL FUNCTION DelayAndSend(nSec, ch, cMsg) Sleep(nSec) ch <- cMsg RETURN NIL FUNCTION PipeDouble(chIn, chOut, n) LOCAL i, v FOR i := 1 TO n v := <- chIn // 수신 chOut <- v * 2 // 2배 후 전송 NEXT RETURN NIL