Concurrency

Some languages support multiple threads, thread-safe data structures and cross-thread communication. Some languages also support asynchronous invocation of functions that may be waiting for an external asynchronous operation (e.g. IO, external process).

Go Concurrency

TypeScript Concurrency


Async/Await

Ability to seamlessly invoke and wait for an asynchronous operation, without blocking the executing thread. This typically requires runtime support to yield to an execution loop, where execution can continue until the asynchronous operation has completed.

Go does not have async/await but uses goroutines and channels for asynchronous operations.

func asyncTask() { fmt.Println("Task started") time.Sleep(2 * time.Second) fmt.Println("Task finished") } func main() { go asyncTask() fmt.Println("Main function continues...") time.Sleep(3 * time.Second) }

TypeScript supports async/await for asynchronous operations.

async function fetchData(url: string): Promise<any> { const response = await fetch(url); return response.json(); } fetchData("https://api.example.com/data") .then((data) => console.log(data)) .catch((error) => console.error(error));

External Async Operations

Support in runtime libraries for native asynchronous operation (for example, file I/O). This alleviates the need to tie up a CPU thread while waiting on an external task to complete.

Go supports asynchronous file processing using goroutines and channels.

import ( "bufio" "fmt" "os" ) func readLines(filePath string, ch chan string) { file, err := os.Open(filePath) if err != nil { close(ch) return } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { ch <- scanner.Text() } close(ch) } func main() { ch := make(chan string) go readLines("example.txt", ch) for line := range ch { fmt.Println(line) } }

TypeScript relies on JavaScript's runtime for external asynchronous operations, such as file I/O or network requests.

const readFile = async (filePath: string) => { const response = await fetch(filePath); return response.text(); }; readFile("/path/to/file.txt") .then((content) => console.log(content)) .catch((error) => console.error("Error reading file:", error));

Multi-Threading

Supports the ability to create and manage preemptive operating system threads.

Go uses goroutines for lightweight multi-threading.

import ( "fmt" "sync" ) func worker(id int, wg *sync.WaitGroup) { defer wg.Done() fmt.Printf("Worker %d started\n", id) } func main() { var wg sync.WaitGroup for i := 1; i <= 5; i++ { wg.Add(1) go worker(i, &wg) } wg.Wait() fmt.Println("All workers finished") }

Not Supported


Atomic Operations and Mutexes

Supports the ability to coordinate access to shared resources (e.g. memory) across threads in the same process, and atomic operations (e.g. interlocked increment).

Go provides sync/atomic and sync.Mutex for thread-safe operations.

import ( "fmt" "sync" "sync/atomic" ) var counter int64 func increment(wg *sync.WaitGroup) { defer wg.Done() atomic.AddInt64(&counter, 1) } func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go increment(&wg) } wg.Wait() fmt.Println("Counter:", counter) }

Not Supported


Semaphores and inter-thread communication

Ability to communicate between threads using semaphores and other inter-thread communication methods.

Semaphores and Inter-Thread Communication

Go uses channels to simulate semaphores.

import ( "fmt" "time" ) func worker(id int, sem chan struct{}) { sem <- struct{}{} fmt.Printf("Worker %d started\n", id) time.Sleep(time.Second) fmt.Printf("Worker %d finished\n", id) <-sem } func main() { sem := make(chan struct{}, 3) for i := 1; i <= 5; i++ { go worker(i, sem) } time.Sleep(5 * time.Second) }

Semaphores and Inter-Thread Communication

Not Supported


OS signal handlers

Integration with operating system signals (or Wait Handles).

OS Signal Handlers

Go supports OS signal handling using the os/signal package.

import ( "fmt" "os" "os/signal" "syscall" ) func main() { sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) fmt.Println("Waiting for signal...") <-sigs fmt.Println("Signal received. Exiting...") }

OS Signal Handlers

Not Supported


Shared Memory

Ability to use shared memory for inter-process communication, either natively or through a commonly used library.

Go does not have built-in shared memory but can use memory-mapped files.

import ( "fmt" "os" "syscall" ) func main() { file, err := os.Create("shared_memory") if err != nil { panic(err) } defer file.Close() data, err := syscall.Mmap(int(file.Fd()), 0, 1024, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED) if err != nil { panic(err) } copy(data, "Hello, shared memory!") fmt.Println(string(data[:20])) }

Not Supported