From 10030f4935950f45c8240158a4fe5e0b80ec986a Mon Sep 17 00:00:00 2001 From: Amit Murthy Date: Wed, 1 Apr 2015 10:58:00 +0530 Subject: [PATCH] added docs --- NEWS.md | 4 ++++ doc/manual/faq.rst | 44 +++++++++++++++++++++++++++++++++++++++++ doc/stdlib/parallel.rst | 16 +++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/NEWS.md b/NEWS.md index e35771e0690bae..3ec9360a39befd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -237,6 +237,10 @@ Library improvements * `readavailable` returns a byte vector instead of a string. + * `lock` and `unlock` which operate on `ReentrantLock`. Useful to lock a stream during + concurrent writes from multiple tasks + + Deprecated or removed --------------------- diff --git a/doc/manual/faq.rst b/doc/manual/faq.rst index 87e5196c1a6d69..efba783b285eb4 100644 --- a/doc/manual/faq.rst +++ b/doc/manual/faq.rst @@ -833,6 +833,50 @@ potential performance optimizations that can be achieved by other means (e.g., using explicit loops), operators like ``+=`` and ``*=`` work by rebinding new values. +Asynchronous IO and concurrent synchronous writes +------------------------------------------------- + +Why do concurrent writes to the same stream result in inter-mixed output? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +While the streaming I/O API is synchronous, the underlying implementation +is fully asynchronous. + +The following:: + + @sync for i in 1:3 + @async print(i, " Foo ", " Bar ") + end + +results in:: + 123 Foo Foo Foo Bar Bar Bar + +This is happening because, while ``print(i, " Foo ", " Bar ")`` is synchronous, +internally, the writing of each argument yields to other tasks while waiting for +that part of the I/O to complete. + +``println`` to asynchronous streams like STDOUT, TcpSockets, "locks" the stream +during a call. Consequently changing ``print`` to ``println`` in the above example +results in:: + + 1 Foo Bar + 2 Foo Bar + 3 Foo Bar + +For other functions and streams, etc, you could lock your writes with a ``ReentrantLock`` +like this:: + + l = ReentrantLock() + @sync for i in 1:3 + @async begin + lock(l) + try + print(i, " Foo ", " Bar ") + finally + unlock(l) + end + end + Julia Releases ---------------- diff --git a/doc/stdlib/parallel.rst b/doc/stdlib/parallel.rst index 5bcec5626808c3..6f8f1542697c8c 100644 --- a/doc/stdlib/parallel.rst +++ b/doc/stdlib/parallel.rst @@ -98,6 +98,22 @@ Tasks Block the current task for a specified number of seconds. The minimum sleep time is 1 millisecond or input of ``0.001``. +.. function:: ReentrantLock() + + Creates a reentrant lock. The same task can acquire the lock as many times + as required. Each lock must be matched with an unlock. + +.. function:: lock(l::ReentrantLock) + + Associates ``l`` with the current task. If ``l`` is already locked by a different + task, waits for it to become available. The same task can acquire the lock multiple + times. Each "lock" must be matched by an "unlock" + +.. function:: unlock(l::ReentrantLock) + + Releases ownership of the lock by the current task. If the lock had been acquired before, + it just decrements an internal counter and returns immediately. + General Parallel Computing Support ----------------------------------