about summary refs log tree commit diff
path: root/doc/tutorial/task.md
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-01-10 19:41:57 -0800
committerNiko Matsakis <niko@alum.mit.edu>2012-01-10 19:57:00 -0800
commitef895b96320a9d5c64090bad1c8a147b0431eef1 (patch)
tree416e6d05266fe8d3afcb199024121f0c61e8aa0a /doc/tutorial/task.md
parent441a42c5d2707ae93a8be3c6be5c426e7416e50b (diff)
downloadrust-ef895b96320a9d5c64090bad1c8a147b0431eef1.tar.gz
rust-ef895b96320a9d5c64090bad1c8a147b0431eef1.zip
update various parts of the tutorial
Diffstat (limited to 'doc/tutorial/task.md')
-rw-r--r--doc/tutorial/task.md75
1 files changed, 74 insertions, 1 deletions
diff --git a/doc/tutorial/task.md b/doc/tutorial/task.md
index 50a7ad193ec..b373e27dc21 100644
--- a/doc/tutorial/task.md
+++ b/doc/tutorial/task.md
@@ -1,3 +1,76 @@
 # Tasks
 
-FIXME to be written
+Rust supports a system of lightweight tasks, similar to what is found
+in Erlang or other actor systems.  Rust tasks communicate via messages
+and do not share data.  However, it is possible to send data without
+copying it by making use of [unique boxes][uniques] (still, the data
+is owned by only one task at a time).
+
+[uniques]: data.html#unique-box
+
+NOTE: As Rust evolves, we expect the Task API to grow and change
+somewhat.  The tutorial documents the API as it exists today.
+
+## Spawning a task
+
+Spawning a task is done using the various spawn functions in the
+module task.  Let's begin with the simplest one, `task::spawn()`, and
+later move on to the others:
+
+    let some_value = 22;
+    let child_task = task::spawn {||
+        std::io::println("This executes in the child task.");
+        std::io::println(#fmt("%d", some_value));
+    };
+
+The argument to `task::spawn()` is a [unique closure](func) of type
+`fn~()`, meaning that it takes no arguments and generates no return
+value.  The effect of `task::spawn()` is to fire up a child task that
+will execute the closure in parallel with the creator.  The result is
+a task id, here stored into the variable `child_task`.
+
+## Ports and channels
+
+Now that we have spawned a child task, it would be nice if we could
+communicate with it.  This is done by creating a *port* with an
+associated *channel*.  A port is simply a location to receive messages
+of a particular type.  A channel is used to send messages to a port.
+For example, imagine we wish to perform two expensive computations
+in parallel.  We might write something like:
+
+    let port = comm::port::<int>();
+    let chan = comm::chan::<int>(port);
+    let child_task = task::spawn {||
+        let result = some_expensive_computation();
+        comm::send(chan, result);
+    };
+    some_other_expensive_computation();
+    let result = comm::recv(port);
+
+Let's walk through this code line-by-line.  The first line creates a
+port for receiving integers:
+
+    let port = comm::port::<int>();
+    
+This port is where we will receive the message from the child task
+once it is complete.  The second line creates a channel for sending
+integers to the port `port`:
+
+    let chan = comm::chan::<int>(port);
+
+The channel will be used by the child to send a message to the port.
+The next statement actually spawns the child:
+
+    let child_task = task::spawn {||
+        let result = some_expensive_computation();
+        comm::send(chan, result);
+    };
+
+This child will perform the expensive computation send the result
+over the channel.  Finally, the parent continues by performing
+some other expensive computation and then waiting for the child's result
+to arrive on the port:
+
+    some_other_expensive_computation();
+    let result = comm::recv(port);
+