1 use crate::task::JoinHandle; 2 3 use std::future::Future; 4 5 cfg_rt! { 6 /// Spawns a new asynchronous task, returning a 7 /// [`JoinHandle`](super::JoinHandle) for it. 8 /// 9 /// The provided future will start running in the background immediately 10 /// when `spawn` is called, even if you don't await the returned 11 /// `JoinHandle`. 12 /// 13 /// Spawning a task enables the task to execute concurrently to other tasks. The 14 /// spawned task may execute on the current thread, or it may be sent to a 15 /// different thread to be executed. The specifics depend on the current 16 /// [`Runtime`](crate::runtime::Runtime) configuration. 17 /// 18 /// It is guaranteed that spawn will not synchronously poll the task being spawned. 19 /// This means that calling spawn while holding a lock does not pose a risk of 20 /// deadlocking with the spawned task. 21 /// 22 /// There is no guarantee that a spawned task will execute to completion. 23 /// When a runtime is shutdown, all outstanding tasks are dropped, 24 /// regardless of the lifecycle of that task. 25 /// 26 /// This function must be called from the context of a Tokio runtime. Tasks running on 27 /// the Tokio runtime are always inside its context, but you can also enter the context 28 /// using the [`Runtime::enter`](crate::runtime::Runtime::enter()) method. 29 /// 30 /// # Examples 31 /// 32 /// In this example, a server is started and `spawn` is used to start a new task 33 /// that processes each received connection. 34 /// 35 /// ```no_run 36 /// use tokio::net::{TcpListener, TcpStream}; 37 /// 38 /// use std::io; 39 /// 40 /// async fn process(socket: TcpStream) { 41 /// // ... 42 /// # drop(socket); 43 /// } 44 /// 45 /// #[tokio::main] 46 /// async fn main() -> io::Result<()> { 47 /// let listener = TcpListener::bind("127.0.0.1:8080").await?; 48 /// 49 /// loop { 50 /// let (socket, _) = listener.accept().await?; 51 /// 52 /// tokio::spawn(async move { 53 /// // Process each socket concurrently. 54 /// process(socket).await 55 /// }); 56 /// } 57 /// } 58 /// ``` 59 /// 60 /// To run multiple tasks in parallel and receive their results, join 61 /// handles can be stored in a vector. 62 /// ``` 63 /// # #[tokio::main(flavor = "current_thread")] async fn main() { 64 /// async fn my_background_op(id: i32) -> String { 65 /// let s = format!("Starting background task {}.", id); 66 /// println!("{}", s); 67 /// s 68 /// } 69 /// 70 /// let ops = vec![1, 2, 3]; 71 /// let mut tasks = Vec::with_capacity(ops.len()); 72 /// for op in ops { 73 /// // This call will make them start running in the background 74 /// // immediately. 75 /// tasks.push(tokio::spawn(my_background_op(op))); 76 /// } 77 /// 78 /// let mut outputs = Vec::with_capacity(tasks.len()); 79 /// for task in tasks { 80 /// outputs.push(task.await.unwrap()); 81 /// } 82 /// println!("{:?}", outputs); 83 /// # } 84 /// ``` 85 /// This example pushes the tasks to `outputs` in the order they were 86 /// started in. If you do not care about the ordering of the outputs, then 87 /// you can also use a [`JoinSet`]. 88 /// 89 /// [`JoinSet`]: struct@crate::task::JoinSet 90 /// 91 /// # Panics 92 /// 93 /// Panics if called from **outside** of the Tokio runtime. 94 /// 95 /// # Using `!Send` values from a task 96 /// 97 /// The task supplied to `spawn` must implement `Send`. However, it is 98 /// possible to **use** `!Send` values from the task as long as they only 99 /// exist between calls to `.await`. 100 /// 101 /// For example, this will work: 102 /// 103 /// ``` 104 /// use tokio::task; 105 /// 106 /// use std::rc::Rc; 107 /// 108 /// fn use_rc(rc: Rc<()>) { 109 /// // Do stuff w/ rc 110 /// # drop(rc); 111 /// } 112 /// 113 /// #[tokio::main] 114 /// async fn main() { 115 /// tokio::spawn(async { 116 /// // Force the `Rc` to stay in a scope with no `.await` 117 /// { 118 /// let rc = Rc::new(()); 119 /// use_rc(rc.clone()); 120 /// } 121 /// 122 /// task::yield_now().await; 123 /// }).await.unwrap(); 124 /// } 125 /// ``` 126 /// 127 /// This will **not** work: 128 /// 129 /// ```compile_fail 130 /// use tokio::task; 131 /// 132 /// use std::rc::Rc; 133 /// 134 /// fn use_rc(rc: Rc<()>) { 135 /// // Do stuff w/ rc 136 /// # drop(rc); 137 /// } 138 /// 139 /// #[tokio::main] 140 /// async fn main() { 141 /// tokio::spawn(async { 142 /// let rc = Rc::new(()); 143 /// 144 /// task::yield_now().await; 145 /// 146 /// use_rc(rc.clone()); 147 /// }).await.unwrap(); 148 /// } 149 /// ``` 150 /// 151 /// Holding on to a `!Send` value across calls to `.await` will result in 152 /// an unfriendly compile error message similar to: 153 /// 154 /// ```text 155 /// `[... some type ...]` cannot be sent between threads safely 156 /// ``` 157 /// 158 /// or: 159 /// 160 /// ```text 161 /// error[E0391]: cycle detected when processing `main` 162 /// ``` 163 #[track_caller] 164 pub fn spawn<T>(future: T) -> JoinHandle<T::Output> 165 where 166 T: Future + Send + 'static, 167 T::Output: Send + 'static, 168 { 169 // preventing stack overflows on debug mode, by quickly sending the 170 // task to the heap. 171 if cfg!(debug_assertions) && std::mem::size_of::<T>() > 2048 { 172 spawn_inner(Box::pin(future), None) 173 } else { 174 spawn_inner(future, None) 175 } 176 } 177 178 #[track_caller] 179 pub(super) fn spawn_inner<T>(future: T, name: Option<&str>) -> JoinHandle<T::Output> 180 where 181 T: Future + Send + 'static, 182 T::Output: Send + 'static, 183 { 184 use crate::runtime::{context, task}; 185 186 #[cfg(all( 187 tokio_unstable, 188 tokio_taskdump, 189 feature = "rt", 190 target_os = "linux", 191 any( 192 target_arch = "aarch64", 193 target_arch = "x86", 194 target_arch = "x86_64" 195 ) 196 ))] 197 let future = task::trace::Trace::root(future); 198 let id = task::Id::next(); 199 let task = crate::util::trace::task(future, "task", name, id.as_u64()); 200 201 match context::with_current(|handle| handle.spawn(task, id)) { 202 Ok(join_handle) => join_handle, 203 Err(e) => panic!("{}", e), 204 } 205 } 206 } 207