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).
Concurrency
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