Nemůžu svůj předchozí komentář změnit, tak doplňuji tímto: Místo použití “go fnc(...)” byste v C použil “dispatch_async(queue, ^{ fnc(...); })”, kde queue se vytvoří s DISPATCH_QUEUE_CONCURRENT (default je tuším SERIAL, takže by se nevytížila všechna jádra procesoru). Místo kanálu “done” byste musel použít dispatch_semaphore_t. To je asi vše podstatné.
Není zač, klidně se ozvěte, kdybyste k tomu ještě něco potřeboval. Jinak to s tím clangem není vlastně tak úplně pravda, v libdispatch mají funkce jako dispatch_async i varianty s příponou _f beroucí ukazatel na funkci a ukazatel na data, který se předá asynchronně volané funkci, takže i s gcc se dá libdispatch použít, jen to je trochu méně pohodlné.