You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

70 lines
2.3 KiB

//! This program is an example of how Wasmtime can be used with multithreaded
//! runtimes and how various types and structures can be shared across threads.
// You can execute this example with `cargo run --example threads`
use anyhow::Result;
use std::sync::Arc;
use std::thread;
use std::time;
use wasmtime::*;
const N_THREADS: i32 = 10;
const N_REPS: i32 = 3;
fn main() -> Result<()> {
println!("Initializing...");
// Initialize global per-process state. This state will be shared amonst all
// threads. Notably this includes the compiled module as well as a `Linker`,
// which contains all our host functions we want to define.
let engine = Engine::default();
let module = Module::from_file(&engine, "examples/threads.wat")?;
let mut linker = Linker::new(&engine);
linker.func_wrap("global", "hello", || {
println!("> Hello from {:?}", thread::current().id());
})?;
let linker = Arc::new(linker); // "finalize" the linker
// Share this global state amongst a set of threads, each of which will
// create stores and execute instances.
let children = (0..N_THREADS)
.map(|_| {
let engine = engine.clone();
let module = module.clone();
let linker = linker.clone();
thread::spawn(move || {
run(&engine, &module, &linker).expect("Success");
})
})
.collect::<Vec<_>>();
for child in children {
child.join().unwrap();
}
Ok(())
}
fn run(engine: &Engine, module: &Module, linker: &Linker<()>) -> Result<()> {
// Each sub-thread we have starting out by instantiating the `module`
// provided into a fresh `Store`.
println!("Instantiating module...");
let mut store = Store::new(&engine, ());
let instance = linker.instantiate(&mut store, module)?;
let run = instance.get_typed_func::<(), ()>(&mut store, "run")?;
println!("Executing...");
for _ in 0..N_REPS {
run.call(&mut store, ())?;
thread::sleep(time::Duration::from_millis(100));
}
// Also note that that a `Store` can also move between threads:
println!("> Moving {:?} to a new thread", thread::current().id());
let child = thread::spawn(move || run.call(&mut store, ()));
child.join().unwrap()?;
Ok(())
}