Concurrency

From WikEmacs
Revision as of 13:53, 21 February 2017 by Elvince (talk | contribs) (→‎emacs-async: examples)
Jump to navigation Jump to search

How to write concurrent/asynchronous code in Emacs ?

Async processes

Accept that you can do a lot with just multiple async processes – this is the NodeJs approach; a single Emacs can ask another process to do something and use ProcessSentinels and ProcessFilterFunctions to do quite a lot of processing apparently concurrently but really just in an event loop. As long as the ProcessFilterFunction is not too slow this is fine. Elnode takes this approach to making a scalable webserver in EmacsLisp.

emacs-async

Spawn more Emacs processes to do work for you – JohnWiegley’s Async takes this approach, Elnode has an alternative and Elpakit another alternative. No one has unified this approach yet.

Some async applications are provided as well with emacs-async:

  • Dired-async
  • smtp-mail-async
  • async-bytecomp

Example code:

(async-start
   ;; What to do in the child process
   (lambda ()
     (message "This is a test")
     (sleep-for 3)
     222)

   ;; What to do when it finishes
   (lambda (result)
     (message "Async process done, result should be 222: %s" result)))


Examples:

- in Nikola.el

emacs-deferred

Defer asynchronous tasks – this is what the emacs-deferred library does. It provides facilities to manage asynchronous tasks. The API and implementations were translated from JSDeferred and Mochikit.Async in Javascript. concurrent.el is a higher level library for concurrency, based on `deferred.el’.

Example:

This is a basic deferred chain. This code puts some outputs into message buffer, and then require a number from minibuffer.

(deferred:$
  (deferred:next
    (lambda () (message "deferred start")))
  (deferred:nextc it
    (lambda ()
      (message "chain 1")
      1))
  (deferred:nextc it
    (lambda (x)
      (message "chain 2 : %s" x)))
  (deferred:nextc it
    (lambda ()
      (read-minibuffer "Input a number: ")))
  (deferred:nextc it
    (lambda (x)
      (message "Got the number : %i" x)))
  (deferred:error it
    (lambda (err)
      (message "Wrong input : %s" err))))

Async/Await

Async/Await for Emacs is based on promise.el.

Example of code:

(async-defun example2 ()
  (print (await (wait-async 0.5)))
  (message "---")

  (print (await (wait-async 1.0)))
  (message "---")

  (print (await (wait-async 1.5)))
  (message "---")

  (message "await done"))

Emacs 25's Thread

Thread support has been added to Emacs.

See the discussion at http://thread.gmane.org/gmane.emacs.devel/120530/focus=122664 or the info manual at Thread.