Practical clojure-Parallel Programming

Source: Internet
Author: User
Document directory
  • Agents
  • Concurrency Functions
  • Futures and promises
  • Java-based threading
Agents

Agent is an asynchronous data update mechanism.
But it is also a concurrency mechanism because the agent is implemented based on the thread pool and is sent to different thread pools by sending and sending-off respectively.
The number of threads in the thread pool corresponding to send is basically equal to the number of cup cores. Therefore, multiple send commands are automatically processed concurrently Based on the concurrency of the number of cup cores.

Use this mechanism to implement concurrency

Concurrency functionspmap

Pmap is an evolutionary version of map, but it submits elements in each set to a thread to execute the function.

Pmap is partiallyLazyIn that the entire result set is not realized unless required, but the parallel computation does run ahead of the consumption to some degree.

For example, define the test function first, and sleep 1 s before actually executing the function.

(defn make-heavy [f]  (fn [& args]    (Thread/sleep 1000)      (apply f args)))

Through the simple comparison of the following time, we will understand the difference.

user=> (time (doall (map (make-heavy inc) [1 2 3 4 5])))"Elapsed time: 5002.96291 msecs"(2 3 4 5 6)user=> (time (doall (pmap (make-heavy inc) [1 2 3 4 5])))"Elapsed time: 1031.941815 msecs"(2 3 4 5 6)

Pvalues

Pvalues takes any number of expressions and returns a lazy sequence of the values of each expression, evaluated in parallel.

User => (pvalues (+ 5 5) (-5 3) (* 2 4 ))

(10 2 8)

Pcils

Pcalltakes any number of No-Argument functions and returns a lazy sequence of their return values, executing them in parallel.

User => (pcils # (+ 5 2) # (* 2 5 ))

(7 10)

 

Overhead and Performance

Concurrency is so good. Is it necessary to use concurrency in all situations?

Certainly not. Concurrency itself also requires overhead. If the thread concurrency saves too little time, it will be worth the candle.

Let's look at the following extreme example. Concurrency is much slower, because the time is spent on the overhead of concurrency.

user=> (time (dorun (map inc (range 1 1000))))"Elapsed time: 9.150946 msecs"user=> (time (dorun (pmap inc (range 1 1000))))"Elapsed time: 182.349073 msecs"

Futures and promises

Futures and promises are two slightly more low-level threading constructs, too red by the similar features available in the Java 6 concurrency API. they are simple to understand, simple to use, and provide a very direct way to spawn threads using native clojure syntax.

Futures

A clojure future represents a computation, running in a single thread.

User => (DEF my-Future (* 100 100) # 'user/My-futureuser => @ My-future; if the thread is not executed, it will block 10000

 

You can see that macro future encapsulates the future-call function. You can also call this function directly, but it is more troublesome.

(defmacro future  [& body] `(future-call (fn [] ~@body)))

Future-cancel

It is possible to attempt to cancel a future that hasn't yet finished executing.

Future-canceled?

Future-canceled? Takes a single future as an argument and returns true if it has been canceled.

Future-done?

Future-done? Takes a single future as an argument and returns true if the future's execution is complete, otherwise false.

Future?

Future? Takes a single value as an argument and returns true if it is a future, otherwise false.

 

Promises

A promise is a value that may not yet exist. If a promise is dereferenced before its value is set, the dereferencing thread blocks until a value is delivered to the promise.

It can be used for synchronization and coordination among multiple threads and is used with caution, which may easily lead to deadlocks.

User => (DEF mypromise (promise) # 'user/mypromiseuser => @ mypromise; causes the main thread to block user => (DEF mypromise (promise )) # 'user/mypromiseuser => (deliver mypromise 5) # <AFN $ ideref $ db53459f @ c0f1ec: 5> User => @ mypromise 5

Java-based threading

If none of clojure's other concurrency tools meet your needs for any reason, there's always the option

Falling back to Java's native threading capabilities.

user=> (.start (Thread. #(println "hello")))nilhello

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.