# Concurrency

> Concurrency in Langoost with the thread module — spawning goroutines, async futures, channels, mutexes, and sharing state across isolated VMs.

# Concurrency

Concurrency lives in the `thread` module. It is **VM-based**: each spawned
function runs in its own isolated VM with a copy of the current globals. That
isolation is what keeps concurrent work safe — tasks don't share mutable state
unless you opt in through the runtime store.

```goost
import thread
```

## Spawning goroutines

```goost
import thread

thread.core.spawn(fn() {
    println("running in the background")
})
```

Other `thread.core` helpers: `sleep(ms)`, `cpus()`, `goroutines()`.

## Async futures

Run work and await its result:

```goost
import thread
import time

let future = thread.async.run(fn() {
    time.timer.sleep(100)
    return "done"
})

println(thread.async.await(future))   // "done"
```

## Channels

Typed message passing between tasks:

```goost
import thread

let ch = thread.channel.new(10)        // buffered channel, capacity 10

thread.core.spawn(fn() {
    thread.channel.send(ch, "hello from goroutine")
})

let msg = thread.channel.recv(ch)
println(msg)
```

Channel functions: `new(capacity)`, `send`, `recv`, `recvTimeout(id, ms)`,
`close`, `len`, `cap`.

## Locks & primitives

The `thread` module also provides the usual primitives:

| Sub-module | Purpose |
| --- | --- |
| `thread.mutex` | Mutual-exclusion lock (`lock`, `unlock`, `tryLock`) |
| `thread.rwlock` | Reader/writer lock |
| `thread.semaphore` | Bounded concurrency (`acquire`, `release`) |
| `thread.atomic` | Atomic integer (`load`, `store`, `add`, `cas`) |
| `thread.pool` | Worker pool (`submit`, `wait`) |
| `thread.scheduler` | Run a set of functions in sequence |

```goost
import thread

let mu = thread.mutex.new()

fn safeIncrement() {
    thread.mutex.lock(mu)
    // ... modify shared state ...
    thread.mutex.unlock(mu)
}
```

## Sharing state across VMs

Because spawned tasks (and HTTP requests) run in isolated VMs, share data
through the global store in `runtime.core`:

```goost
import runtime
import thread

runtime.core.share("counter", "0")

fn worker() {
    let val = toInt(runtime.core.fetch("counter"))
    runtime.core.share("counter", toString(val + 1))
}

thread.core.spawn(worker)
thread.core.spawn(worker)
```

Guard read-modify-write sequences with a `thread.mutex` when correctness under
contention matters.