Message-passing concurrency in Python

6,561 views

Published on

Concurrency and parallelism in Python are always hot topics. This talk will look the variety of forms of concurrency and parallelism. In particular this talk will give an overview of various forms of message-passing concurrency which have become popular in languages like Scala and Go. A Python library called python-csp which implements similar ideas in a Pythonic way will be introduced and we will look at how this style of programming can be used to avoid deadlocks, race hazards and "callback hell".

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,561
On SlideShare
0
From Embeds
0
Number of Embeds
3,485
Actions
Shares
0
Downloads
23
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Message-passing concurrency in Python

  1. 1. Message-passing concurrency in Python Sarah Mount – @snim2 EuroPython 2014 Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 1 / 27
  2. 2. 1 Why multicore? 2 Message passing: an idea whose time has come (back) 3 Message passing: all the cool kids are doing it 4 Design choices in message passing languages and libraries 5 Message passing in Python too! Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 2 / 27
  3. 3. Section 1 Why multicore? Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 3 / 27
  4. 4. Why multicore? (1/2) Feature size (mm) vs time (year). CPU sizes are shrinking! Get the raw data here: http://cpudb.stanford.edu/ Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 4 / 27
  5. 5. Why multicore? (2/2) New platforms, such as this board from Adapteva Inc. which reportedly runs at 50GFPLOPS/Watt. Photo c Adapteva Inc. Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 5 / 27
  6. 6. Section 2 Message passing: an idea whose time has come (back) Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 6 / 27
  7. 7. Message passing concurrency Tony Hoare CSPa (Communicating Sequential Processes) was invented by Tony Hoare in the late 70s / early 80s as a response to the difficulty of reasoning about concurrent and parallel code. It was implemented as the OCCAM programming language for the INMOS Transputer. a other process algebras are available Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 7 / 27
  8. 8. Message passing concurrency CSP1 take the view that computation consists of communicating processes which are individually made up of sequential instructions. The communicating processes all run ”at the same time” and share no data. Because they do not share data they have to cooperate by synchronising on events. A common form of synchronisation (but not the only one) is to pass data between processes via channels. THINK UNIX processes communicating via pipes. BEWARE CSP is an abstract ideas which use overloaded jargon, a process or an event need not be reified as an OS process or GUI event. . . 1 other process algebras are available Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 8 / 27
  9. 9. Benefits of message passing Threads and locking are tough! Deadlocks, starvation, race hazards are tough. Locks do not compose easily, errors in locking cannot easily be recovered from, finding the right level of granularity is hard. CSP does not exhibit race hazards, there are no locks, the hairy details are all hidden away in either a language runtime or a library. WIN! Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 9 / 27
  10. 10. Section 3 Message passing: all the cool kids are doing it Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 10 / 27
  11. 11. UNIX 1 $ cat mydata.csv | sort | uniq | wc -l Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 11 / 27
  12. 12. Go 1 func main () { 2 mychannel := make(chan string) 3 go func () { 4 mychannel <- "Hello world!" 5 }() 6 fmt.Println(<-mychannel) 7 } Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 12 / 27
  13. 13. Rust 1 fn main () { 2 let (chan , port) = channel (); 3 4 spawn(proc () { 5 chan.send("Hello world!"); 6 }); 7 8 println !("{:s}", port.recv ()); 9 } Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 13 / 27
  14. 14. Scala 1 object Example { 2 class Example extends Actor { 3 def act = { 4 receive { 5 case msg => println(msg) 6 } 7 } 8 } 9 def main(args:Array[String ]) { 0 val a = new Example 1 a.start 2 a ! "Hello world!" 3 } 4 } Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 14 / 27
  15. 15. python-csp2 1 @process 2 def client(chan ): 3 print chan.read () 4 @process 5 def server(chan ): 6 chan.write(’Hello world!’) 7 8 if __name__ == ’__main__ ’: 9 ch = Channel () 0 Par(client(ch), server(ch)). start () 2 http://github.com/snim2/python-csp Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 15 / 27
  16. 16. naulang3 : building on the RPython toolchain 1 let f = fn(mychannel) { 2 mychannel <- "Hello world!" 3 } 4 let mychannel = chan () 5 async f(mychannel) 6 print <: mychannel 3 Samuel Giles (2014) Is it possible to build a performant, dynamic language that supports concurrent models of computation? University of Wolverhampton BSc thesis Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 16 / 27
  17. 17. naulang4 : building on the RPython toolchain Table : Results from a tokenring benchmark @SamuelGiles Min (µs) Max (µs) Mean (µs) s.d. Go 1.1.2 99167 132488 100656 1590 Occam-π 68847 73355 69723 603 naulang 443316 486716 447894 6507 naulang JIT 317510 589618 322304 10613 naulang (async) 351677 490241 354325 6401 naulang JIT (async) 42993 49496 44119 295 http://github.com/samgiles/naulang 4 Samuel Giles (2014) Is it possible to build a performant, dynamic language that supports concurrent models of computation? University of Wolverhampton BSc thesis Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 17 / 27
  18. 18. Aside: Did those benchmarks matter? That was a comparison between naulang and two compiled languages. The benchmark gives us some reason to suppose that a dynamic language (built on the RPython chain) can perform reasonably well compared to static languages. Does this matter? We don’t want message passing to become a bottleneck in optimising code. . . Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 18 / 27
  19. 19. Section 4 Design choices in message passing languages and libraries Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 19 / 27
  20. 20. Synchronous vs. asynchronous channels Synchronous channels block on read / write - examples include OCCAM, JCSP, python-csp, UNIX pipes. Asynchronous channels are non-blocking - examples include Scala, Rust. Some languages give you both - examples include Go. Synchronous channels are easier to reason about (formally) and many people believe are easier to use. Most languagues include some extra features to support synchronicity, e.g. if you are waiting to read from a number of channels you can select or ALTernate one that is ready soonest. Aside: with some checks and balances to avoid starvation! Asynchronous channels are sometimes thought to be faster. Like most claims about speed, this isn’t always true. Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 20 / 27
  21. 21. Uni or bidirectional channels? Point to point? The well engineered Java CSP (JCSP) JCSP5 project separates out different sorts of channels types, e.g.: AnyToAnyChannel AnyToOneChannel OneToAnyChannel OneToOneChannel This isn’t very Pythonic, but it can catch errors in setting up a network of channels in a message passing system. 5 http://www.cs.kent.ac.uk/projects/ofa/jcsp/ Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 21 / 27
  22. 22. Mobile or immobile channels A mobile channels can be sent over another channel at runtime. This means that the network of channels can change its topology dynamically at runtime. Why might we want to do this? our processes are actually running over a network of machines or on a manycore processor. We want to migrate some processes from one node to another to perform load balancing or due to some failure condition within a network. some processes have finished their work and need to be poisoned (destroyed) and any channels associated with them need to be either (destroyed) or re-routed elsewhere. Aside: what happens if we want to poison processes and channels that form a cyclic graph? What if one process dies before it can poison others connected to it? Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 22 / 27
  23. 23. Reifying sequential processes In CSP and actor model languages the paradigm is of a number of sequential processes which run in parallel and communicate via channels (think: UNIX processes pipes). It is up to the language designer how to reify those sequential processes. Common choices are: 1 CSP process is 1 coroutine very fast message passing (OCCAM-π reports a small number of ns), cannot take advantage of multicore. 1 CSP process is 1 OS thread slower message passing; can take advantage of multicore 1 CSP process is 1 OS process very slow message passing; can migrate CSP processes across a network to other machines 1 CSP processes is 1 coroutine many coroutines are multiplexed onto an OS thread 1 CSP processes is 1 OS thread many OS threads are multiplexed onto an OS process etc. Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 23 / 27
  24. 24. Section 5 Message passing in Python too! Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 24 / 27
  25. 25. So many EP14 talks! Does Python have message passing? Sort of. . . Several EP14 talks involve coroutines (lightweight threads) and / or channels, and I’m not even counting really cool innovations like PyPy-stm: Daniel Pope Wedneday 11:00 (on gevent) Christian Tismer, Anselm Kruis Wednesday 11:45 (on Stackless) Richard Wall Friday 11:00 (on Twisted) Benoit Chesneau Friday 12:00 (on Offset) Dougal Matthew Friday 12:00 (on asyncio) Message-passing has already entered the Python ecosystem and there are constructs such as pipes and queues in the multiprocessing library. Could we do better by adopting some of the ideas above from other languages? Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 25 / 27
  26. 26. The (near) future Python for the Parallella will be coming out this Summer, thanks to funding from the Royal Academy of Engineering. If you are interested in this, please keep an eye on the futurecore6 GitHub organization. python-csp is (slowly) moving back into regular development. Will it ever be fast? naulang development continues at http://github.com/samgiles/naulang I will be at the PyPy spring on Saturday working on this. Pull requests and constructive criticism always welcome! 6 http://github.com/futurecore/ Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 26 / 27
  27. 27. Thank you. Sarah Mount – @snim2 Message-passing concurrency in Python EuroPython 2014 27 / 27

×