// Five Goroutine Demo — Go's concurrency power in Harbour syntax // This is impossible in original Harbour! // Copyright (c) 2026 Charles KWON OhJun (charleskwonohjun@gmail.com) FUNCTION Main() LOCAL ch, wg, i, result, nTotal ? "=== Five Goroutine Demo ===" ? "" // --- 1. Basic goroutine with channel --- ? "--- 1. Goroutine + Channel ---" ch := Channel() Go({|c| ChSend(c, "Hello from goroutine!")}, ch) result := ChReceive(ch) ? " Received:", result ? "" // --- 2. Fan-out: 5 goroutines computing in parallel --- ? "--- 2. Fan-out: 5 parallel workers ---" ch := Channel(5) wg := WaitGroup(5) FOR i := 1 TO 5 Go("WORKER", i, ch, wg) NEXT WgWait(wg) FOR i := 1 TO 5 ? " ", ChReceive(ch) NEXT ? "" // --- 3. Producer-Consumer pattern --- ? "--- 3. Producer-Consumer ---" ch := Channel(10) wg := WaitGroup(1) Go("PRODUCER", ch) Go("CONSUMER", ch, wg) WgWait(wg) ? "" // --- 4. Ping-Pong between two goroutines --- ? "--- 4. Ping-Pong ---" ch := Channel() wg := WaitGroup(1) Go("PINGER", ch, 5) Go("PONGER", ch, wg, 5) WgWait(wg) ? "" ? "=== Done! Harbour syntax, Go power. ===" RETURN NIL // Worker: compute id^2, send result to channel FUNCTION Worker(nId, ch, wg) Sleep(0.05) ChSend(ch, Str(nId) + "^2 = " + Str(nId * nId)) WgDone(wg) RETURN NIL // Producer: send 1..10 then sentinel -1 FUNCTION Producer(ch) LOCAL j FOR j := 1 TO 10 ChSend(ch, j) NEXT ChSend(ch, -1) RETURN NIL // Consumer: receive until sentinel, print sum FUNCTION Consumer(ch, wg) LOCAL val, nSum nSum := 0 DO WHILE .T. val := ChReceive(ch) IF val = -1 EXIT ENDIF nSum += val ENDDO ? " Sum of 1..10 =", nSum WgDone(wg) RETURN NIL // Pinger: send "ping" n times FUNCTION Pinger(ch, nCount) LOCAL i FOR i := 1 TO nCount ChSend(ch, "ping " + Str(i)) NEXT RETURN NIL // Ponger: receive and reply n times FUNCTION Ponger(ch, wg, nCount) LOCAL i, msg FOR i := 1 TO nCount msg := ChReceive(ch) ?? " " + msg + " -> pong!" ? "" NEXT WgDone(wg) RETURN NIL