diff --git a/pooled-io.cabal b/pooled-io.cabal
--- a/pooled-io.cabal
+++ b/pooled-io.cabal
@@ -1,5 +1,5 @@
 Name:             pooled-io
-Version:          0.0.1.2
+Version:          0.0.2
 License:          BSD3
 License-File:     LICENSE
 Author:           Henning Thielemann <haskell@henning-thielemann.de>
@@ -26,6 +26,12 @@
   * "Control.Concurrent.PooledIO.InOrder":
     run jobs in parallel with data dependencies like @make -j n@
   .
+  Additionally there is the module
+  "Control.Concurrent.PooledIO.Sequence"
+  that helps to serialize I/O actions from multiple threads.
+  It is certainly most useful in connection with
+  "Control.Concurrent.PooledIO.Independent".
+  .
   Related packages:
   .
   * @lazyio@: interleave IO actions in a single thread
@@ -34,7 +40,7 @@
     but do not throttle concurrency with respect to number of available cores
   .
   * @parallel-tasks@:
-Tested-With:      GHC==7.4.1
+Tested-With:      GHC==7.4.2, GHC==7.8.4, GHC==7.10.1
 Cabal-Version:    >=1.8
 Build-Type:       Simple
 
@@ -43,7 +49,7 @@
   default:     False
 
 Source-Repository this
-  Tag:         0.0.1.2
+  Tag:         0.0.2
   Type:        darcs
   Location:    http://code.haskell.org/~thielema/pooled-io/
 
@@ -67,6 +73,7 @@
     Control.Concurrent.PooledIO.Independent
     Control.Concurrent.PooledIO.Final
     Control.Concurrent.PooledIO.InOrder
+    Control.Concurrent.PooledIO.Sequence
   Other-Modules:
     Control.Concurrent.PooledIO.Monad
 
diff --git a/src/Control/Concurrent/PooledIO/Sequence.hs b/src/Control/Concurrent/PooledIO/Sequence.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Concurrent/PooledIO/Sequence.hs
@@ -0,0 +1,79 @@
+{- |
+Functions for sequencing actions requested from concurrent threads.
+
+Here is an example usage:
+
+> import qualified Control.Concurrent.PooledIO.Independent as Parallel
+> import qualified Control.Concurrent.PooledIO.Sequence as Sequence
+>
+> thread :: Sequence.In -> FilePath -> IO ()
+> thread seqIn name = do
+>    txt <- Sequence.sync seqIn $ readFile (name ++ ".in")
+>    -- evaluate result with ($!!) before sending it to the sequencing thread
+>    Sequence.async seqIn . writeFile (name ++ ".out") $!! processMyText txt
+>    doFurtherStuff
+>    -- block main program until completion
+>    Sequence.sync seqIn $ return ()
+>
+> main :: IO ()
+> main = do
+>    (seqIn, seqOut) <- Sequence.new
+>    void $ forkIO $ Sequence.run seqOut
+>    Parallel.run $ map (thread seqIn) ["a", "b", "c"]
+-}
+module Control.Concurrent.PooledIO.Sequence (In, Out, new, run, async, sync) where
+
+import qualified Control.Concurrent.Split.Chan as Chan
+import qualified Control.Concurrent.Split.MVar as MVar
+
+import Control.Monad (join, forever)
+
+import Data.Tuple.HT (mapPair)
+
+
+type Action = IO ()
+
+newtype In = In (Chan.In Action)
+newtype Out = Out (Chan.Out Action)
+
+
+new :: IO (In, Out)
+new = fmap (mapPair (In,Out)) Chan.new
+
+{- |
+Run the sequencing thread.
+You will usually fork it.
+-}
+run :: Out -> IO ()
+run (Out chan) =
+   forever $ join $ Chan.read chan
+
+{- |
+This is primarily intended for output functions.
+You should make sure that the emitted data is evaluated before calling 'async'.
+Otherwise the sequencing thread will evaluate it
+and thus not much parallelization will happen.
+
+Example:
+
+> async seqIn . writeFile "foobar.txt" $!! show result
+-}
+async :: In -> IO () -> IO ()
+async (In chan) act =
+   Chan.write chan act
+
+{- |
+This is primarily intended for input functions.
+You should also call it at the end of a thread in order to make sure
+that all your asynchronous actions are completed.
+It will actually also wait for the actions that were requested by other threads.
+However, I think this should not hurt
+since after completion of the current thread
+another one will be started and it will certainly begin with an input action,
+which has to be queued anyway.
+-}
+sync :: In -> IO a -> IO a
+sync chan act = do
+   (resultIn, resultOut) <- MVar.newEmpty
+   async chan $ act >>= MVar.put resultIn
+   MVar.take resultOut
