Shai Rosenfeld - Such Blocking, Very Concurrency, Wow
Summary
TLDRThe speaker discusses various models of concurrency and parallelism, highlighting their similarities and differences. They delve into concepts such as threads, mutexes, message passing, and shared memory, as well as different scheduling methods like preemptive and cooperative. The talk emphasizes the importance of understanding these models to effectively handle the complexity of modern computing systems, where doing more things at once is crucial for scaling and performance.
Takeaways
- ๐ The talk focuses on various models of concurrency and parallelism, explaining their similarities and differences.
- ๐ Concurrency is about dealing with multiple things at once, while parallelism is about doing multiple things at once.
- ๐ก Rob Pike differentiates concurrency and parallelism, with concurrency being about structuring programs to do more things, and parallelism about executing them simultaneously.
- ๐ Joe Armstrong's analogy explains concurrency as one coffee machine with two queues, and parallelism as two coffee machines with two queues each.
- ๐ง Operating systems use threads and processes as the primary mechanisms for executing work.
- ๐ Scheduling can be either preemptive, where the system can interrupt tasks at any time, or cooperative, where tasks yield control to others explicitly.
- ๐ค Concurrency models need to coordinate execution, often dealing with atomicity and ensuring data consistency.
- ๐ Mutexes and locks are commonly used in concurrency models to manage access to shared resources and prevent data corruption.
- ๐จ Message passing and shared memory are two primary methods of communication between executing entities in concurrent systems.
- ๐ Different concurrency models have their advantages and disadvantages, and the choice of model depends on the specific requirements and constraints of the problem at hand.
- ๐ The subject of concurrency is vast and complex, with each model deserving deep exploration and understanding.
Q & A
What is the main topic of the discussion?
-The main topic of the discussion is concurrency and scaling, with a focus on different models and their applications in handling multiple tasks simultaneously.
What is the difference between concurrency and parallelism as explained in the transcript?
-Concurrency is about dealing with a lot of things at once, structuring a program to do more things, whereas parallelism is about doing a lot of things at once. Parallelism is a condition that arises when two things are happening literally at the same second, such as running two processes or two threads on a multi-core computer.
What are the two primary ways of executing tasks as mentioned in the transcript?
-The two primary ways of executing tasks are preemptive scheduling, where the system reserves the right to interrupt any task at any time, and cooperative scheduling, where tasks voluntarily yield control to other tasks.
What is the significance of atomicity in the context of concurrency?
-Atomicity is significant in concurrency because it is the fundamental reason why concurrency is challenging. Non-atomic operations can lead to issues like race conditions and data corruption when multiple threads or processes try to modify shared data simultaneously.
How does the use of mutexes address the problem of atomicity?
-Mutexes, or mutual exclusion locks, are used to ensure that only one thread can access a shared resource at a time, thus preventing other threads from interfering and ensuring atomicity of operations.
What are the advantages and disadvantages of using threads with mutexes?
-Advantages include widespread availability and familiarity among programmers. Disadvantages include potential issues with deadlocks, live locks, and the overhead of managing locks.
How does message passing differ from shared memory communication?
-Message passing involves sending and receiving messages between processes or threads, which can avoid the complexity of shared memory management. Shared memory involves writing and reading from shared memory locations, which can lead to atomicity issues if not properly managed.
What is the actor model as explained in the transcript?
-The actor model is a concurrency model that uses message-passing to manage state and communication between entities called actors. Each actor has its own state and mailbox for receiving messages, and they communicate by sending messages to each other's mailboxes.
What are the benefits of using the actor model?
-Benefits include the ability to express concurrency in a concise and object-oriented manner, the avoidance of shared state which reduces the risk of corruption, and the natural fit for distributed systems due to the message-passing nature of actors.
How does event-driven programming differ from other concurrency models?
-Event-driven programming is single-threaded and relies on callbacks and events to handle asynchronous input, without the need for multi-threading or multi-processing. It's typically used in scenarios where resource management is crucial, such as handling a large number of concurrent connections.
What are the challenges of implementing event-driven programming?
-Challenges include the difficulty in debugging due to the loss of context and call stack, the potential for callback hell, and the reliance on state management to navigate the program flow.
Outlines
๐ Introduction to Concurrency and Scaling
The speaker introduces the dense topic of concurrency in computing, encouraging the audience to follow along with detailed slides available online. The discussion is set to explore scaling and concurrency, crucial for performing multiple operations simultaneously. The speaker works at Engine Yard but will focus on general scaling rather than specific services. Cats are humorously included in the presentation as a nod to typical tech talks. The overall aim is to map out various concurrency models and their practical applications.
๐ Understanding Concurrency and Parallelism
This section dives deeper into the definitions and distinctions between concurrency and parallelism. The speaker clarifies these concepts through various authoritative views, including Rob Pike's differentiation: concurrency as handling many things at once and parallelism as doing many things at the same time. The segment includes analogies like queues at coffee machines to make these concepts more relatable and easier to grasp for the audience.
๐ Models of Concurrency: Threads and Mutexes
The discussion moves to practical models of concurrency, starting with the basic 'threads and mutexes'. This model involves threads (units of execution) and mutexes (locks that prevent simultaneous execution of critical sections of code) to manage atomicityโensuring operations complete in whole steps without interruption. The speaker explains how mutexes help prevent data corruption by controlling the sequence of thread operations, highlighting both the advantages and limitations of this approach.
๐ Advanced Concurrency: Threads and Transactions
Exploring more sophisticated concurrency mechanisms, the speaker introduces 'threads and transactions', which uses a transactional memory approach to manage shared data. This model provides an 'optimistic' strategy, where operations assume no data conflicts and only rollback if conflicts occur, similar to database transactions. This section discusses the benefits of increased concurrency and better composability, along with the drawbacks of potential rollback complexities.
๐ฎ Futures and Promises: Asynchronous Programming
The talk progresses to 'futures and promises', a model that allows for asynchronous programming. This approach involves using 'futures' to represent pending results and 'promises' as guarantees of future values. The model facilitates non-blocking operations, where tasks can proceed without waiting for other tasks to complete, thus enhancing efficiency. The speaker covers the advantages of abstraction from direct locking mechanisms and the challenges of potential delays in execution.
๐ Processes and Inter-process Communication (IPC)
Focusing on 'processes and inter-process communication (IPC)', this segment discusses the use of separate processes to perform concurrent tasks, communicating via messages rather than shared memory. This model is especially useful in systems where processes operate independently, reducing the risks of data corruption and deadlock. The speaker explains the use of IPC for scalability and the potential high costs associated with process management.
๐ Communicating Sequential Processes (CSP) and Actors
The presentation examines CSP and the actor model, both of which manage concurrency through message passing between independent agents or 'actors'. Each actor processes messages sequentially, ensuring that operations are isolated and reducing the chances of data conflict. This model is highlighted for its scalability and robustness in systems like telecoms where reliability is critical. The speaker emphasizes the flexibility and potential complexity of implementing these models.
๐ Coroutines and Event-driven Programming
The speaker discusses 'coroutines' and 'event-driven programming', emphasizing their utility in scenarios where non-blocking operations are critical, such as user interfaces and network servers. Coroutines allow for cooperative task management, while event-driven architectures handle tasks as they become actionable, leading to efficient resource use. The segment covers the strengths and weaknesses of these models, particularly in contexts requiring high concurrency with minimal overhead.
๐ Recap and Future Directions in Concurrency
Concluding the presentation, the speaker reiterates that no single concurrency model is universally best, urging the audience to consider the specific needs and constraints of their projects. The talk aims to expand the listeners' understanding of concurrency, providing a foundation for further exploration and innovation in this complex field. The session ends with a Q&A, emphasizing interactive learning and the ongoing development of concurrency technologies.
Mindmap
Keywords
๐กConcurrency
๐กParallelism
๐กMutex
๐กRace Condition
๐กEvent Loop
๐กCallback
๐กActor Model
๐กMessage Passing
๐กShared Memory
๐กPreemptive Scheduling
๐กCooperative Scheduling
Highlights
Concurrency and parallelism are distinct concepts; concurrency is about dealing with many things at once, while parallelism is about doing many things at once.
Rob Pike, creator of Go, differentiates concurrency as structuring programs to do more things, and parallelism as the occurrence of many things happening at once.
Joe Armstrong, creator of Erlang, explains concurrency and parallelism with the analogy of one coffee machine with two queues versus two coffee machines with two queues.
The fundamental challenge in concurrency is atomicity; ensuring operations are executed in a single, uninterruptible run is crucial for data integrity.
Operating systems execute work through threads and processes, with threads being either native OS threads or green threads within a virtual machine.
Scheduling mechanisms for executing tasks include preemptive scheduling, where the OS can interrupt tasks, and cooperative scheduling, where tasks voluntarily yield control.
Concurrency models can be broadly categorized by their communication methods: shared memory, message passing, and channels.
The use of mutexes (locks) is a common method to handle atomicity in concurrent programming, ensuring that shared data is accessed by only one thread at a time.
Software transactional memory (STM) provides an optimistic approach to concurrency, allowing for rollbacks in case of conflicts, similar to database transactions.
Message passing through channels or futures and promises is a concurrency model that abstracts away the need for locks, handling communication between executing entities.
Inter-process communication (IPC) is a method for separate processes to communicate, often avoiding shared memory to prevent corruption and simplify atomicity management.
Communicating Sequential Processes (CSP) is a model that uses channels for message passing, influencing languages like Go, which heavily relies on channels for concurrency.
The Actor model is similar to CSP but uses actors with individual mailboxes for message passing, making it akin to object-oriented threads.
Coroutines are single-threaded, cooperative concurrency models that allow for pausing and resuming execution, useful for managing local state without locks.
Event-driven programming is a concurrency model that uses a single execution thread, relying on callbacks, event handlers, and an event loop to manage non-blocking operations.
Event-driven programming can scale well in terms of resource usage, as seen in web servers like Nginx, which handle many connections with fewer threads than traditional models.
The choice of concurrency model should be influenced by the specific needs of the application, considering factors like simplicity, scalability, and the potential for parallelism.
Transcripts
all right uh so such blocking very
concurrency
wow that's uh what i'm going to talk
about um so the
the slides are going to be pretty dense
today i'm going to talk about a lot of
material so if you guys
um yesterday when i was sitting here i
had internet so if you guys want to pull
this up on your
laptop or ipad or whatever you can pull
this up it's
this link it's basically my name and
then
sb vc such blocking very concurrency so
you can
pull that up and follow along so like
jonathan says i work at engine yard it's
a company that basically
provisions stuff like windows azure and
amazon and provides you with a
ready stack to use your application with
so you just
it's basically similar to heroku and
other platforms as the services
that you just push your application
there similar to google app engine as
well
you just push your application and then
it kind of works but i'm not going to
talk about
engineer today i'm going to talk about
cats
and because every tech talk needs a cat
and actually the other day when we were
at that beer
tap place jonathan said that we should
put
every tech talking is a cat in it so i
put some images here for you to
enjoy there's a cat there's another cat
all right well i really want to talk
about scaling because this is scale conf
so it's actually not going to be related
to engine yard
what i want to talk about is uh scaling
and concurrency
so really what what is scaling right we
have a certain set amount of time to do
something
we have these things that we need to do
and then we need to do more of them
and that's what scaling is right so
scaling is really doing more things at
once
so when i was invited to come here i
decided okay i'm going to talk about all
the ways you can do more things
okay i'm going to talk about all the
talk about all the things
that you can do and to accomplish this
goal to do more things
so i'm going to map them all out right
and i decided to talk about concurrency
and parallelism because apparently
they're different
and i kept on kind of looking into it
and i realized well there's like a ton
of
models it wasn't really going to put me
off i was going to talk about all the
things
and there's just a ton of calculus and
all these you know mathematical models
and it just keeps on going and going and
going so i decided you know maybe i'm
not going to talk about everything in
depth
but i do i do want to to talk about
concurrency models
so what i ended up deciding on is i'm
going to kind of do a tour
of the different models that exist i'm
going to talk about
some general concepts that all these
models kind of share
and then i'm going to go through some of
the models and talk about them and kind
of
iterate some advantages and
disadvantages that each one of these
things have
and then i'm going to let you sit with
it in your own head and figure it out
because really
this is a huge subject it's i'm
surprised myself that i put all this
information in one in one presentation
because really even one specific model
you can spend a whole lifetime on
right this is it's a really big subject
and so i'm
going to leave it for you guys to to dig
in further
so talk about uh start with the the
general concepts which are the common
ingredients that all these models share
and what i've kind of mapped it out to
is the following things that i'm going
to start
just diving into so concurrency versus
parallelism are apparently different
right so what what is the difference
i found this on the internet says on the
haskell blog and it says not all
programmers agree on the meaning of the
terms parallelism and concurrency
they may define them in different ways
or do not distinguish them
at all and so i decided okay well let's
ask the authority figures
what what is going on and so rob pike
created go was a pretty good authority
figure for concurrency
says that concurrency is about dealing
with a lot of things at once and
parallelism is about doing a lot of
things at once
and they're they're similar but they're
a little different and he basically
talks
in this um this talk that he gave in san
francisco it's a really good talk and
you're going to have resources and links
that you guys can check out on the
slides but he basically says that
concurrency
is is structuring your program your
program to do more things
whereas parallelism is is the fact that
it happens a lot at once
and so the other authority figure i
decided to ask was monty python
figures and actually it was joe
armstrong
so erling is another highly concurrent
language and he
says when concurrency is two queues one
coffee machine
and parallelism is two queues two coffee
machines that's how he decides to
explain it to a five-year-old
it's a similar it's a similar concept
you can see parallelism is is happening
at the same time whereas concurrency is
just the way you structure it to have
two lines
happen at the same time but you still
only have this one
one coffee machine and so the way that
that it made sense to me
was that parallelism is really a
condition that arises when two things
are happening literally at the same
second so for example if you run
two processes or two threads on a
multi-core computer and they're
executing at the same second that's
parallel whereas concurrency is kind of
it's almost like a super set
of parallelism it doesn't have to be
parallel but it can be
and that's it's not entirely true
because some i've i've also read that
some people say that there's you know
there are certain things that are
parallel and not concurrent but i think
it's more of like a
philosophical programming kind of debate
thing so
so operating system mechanisms are we
have things that we need to execute to
do work right so how do we execute these
things
so really it's just threads and
processes right there's not there's not
much else to it
you have a regular operating system
process a linux task
and we have threads native operating
system threads
again same thing but they they just
share memory instead of
being contained self-contained and then
there are green threads
and virtual machine processes these are
basically kind of user level threads
that are done within the virtual machine
that you're running
or the interpreter and they're they're
similar to regular threads except
they're not on the operating system
level and for the purpose of the talk
i'm just going to really uh split it
into
processes and threads and the reason i
put leonardo dicaprio there is because
it's a virtual machine process it's a
process within a process so it's kind of
conception
so scheduling so we have these these
executing things right process and
threads is what i'm going to refer to
now as an executing thing
and these executing things need to be
scheduled so how how do they run like
when do they run
so there's really only two ways you can
that this is usually done right there's
the preemptive way
and then there's the cooperative way and
the preemptive way
is basically saying we reserve the right
to attack anyone at any given time so
basically anything can happen
right you have one thing that's running
and then who knows what happens who
knows how long has passed something else
gets invoked at the same
you know immediately and so that's you
know interrupts our
preemptive and scheduling threads and
operating system are preemptive
and that's preemption whereas the
cooperative uh
way of scheduling is basically it's kind
of handing off the baton to something
it's like
fred is running fred is doing all this
stuff and then he stops he pauses and
says okay
i'm done it's now your turn to do
something and then joe picks up the
baton and starts
you know making hot potatoes or
something stops when he's done he passes
on to harry and then the circle kind of
goes around but they're all
they're all working together and this is
the cooperative way of scheduling
so really what what this is is that it
relies on the program or the thing
that's running the executing thing
that's running to say i'm done
it's now your turn
so this is probably the most important
um common
common ingredient that all these things
share because really we have all these
things that are executing they're
running either preemptively or
cooperative
cooperatively or whatever but they they
need to coordinate between them what's
happening right because they're all
doing work with the same stuff so how do
they how do we make sure
that these things don't trip over each
other this kind of leads me into the
concept of
atomicity and atomicity is basically
the the fundamental reason of why
concurrency is hard
right this is the reason that that you
know people do phds on this stuff
is because things are not atomic and the
reason that it can create havoc is
because if you you look at that example
right there
you'll see you know the first thread is
trying to increment a variable right in
this case we want two threads to
increment a variable the first thread is
going to read the variable from ram
it's going to push it into the cpu into
some cpu register make the calculation
to
you know up it by one and save its local
stack and then
the other thread gets preemptively
scheduled it reads the variable from ram
and if you can see the first thread
hasn't written it back to memory yet so
it reads it and it's zero
and then uh the first thread writes it
back to ram the second thread uh picks
up from where it's left it increments it
it's one
and it pushes it down to ram and it's
it's one whereas in reality this should
have been two
right that's a serious problem because
you can't trust your programs doing what
you're doing it's it's bad
right and um yeah it's really bad
people can die so the way that you
commute these things communicate with
each other
is there really two kind of main ways to
do it one is is shared memory
and shared memory is basically writing
some state or some value to
uh you know variable in in ram basically
and then the other executing thing looks
at that and decides what in it what it
needs
to do according to that value right now
shared memory and it's a pretty
efficient means
of passing data between between these
executing things
the other way is through message passing
and this is a
we'll get to it later but message
passing is essentially instead of
invoking a certain function
that needs to be done you you pass the
message of what needs to be done to some
kind of proxy and then that thing
decides to you know it could either be
invoked automatically you know at the
same time or it could be done later
or whatever but the the idea of message
passing is that you don't directly
invoke something you just
tell something to happen
and um and channels is kind of a subset
to me it's a subset of message passing
except that your interface is through a
stream so instead of uh you having to
like
send a certain message and and have to
deal with that your api is basically
like a file
and this is pretty pretty cool because
if you think about like the unix
paradigm of everything as a file
you know having a file stream api for
message passing is
is nice so
i'm going to talk about the model so
those were kind of the the general
concepts that we're going to use to
try and categorize all these different
things in a way that
that hopefully will be easier to kind of
grasp and then go deeper
you know on your own time so this is the
link again
um because the slides are going to be
you know pretty dense
if you haven't pulled it up you're
welcome to pull it up now
so uh this is the this table that took
me quite a while to put together
and it's trying to take all these uh
these things that we've talked about and
trying to classify all of the the models
that we have
and i'm going to uh iterate through
every one of these and you'll see
you know the um you'll see this the
table kind of row on the top so you can
refer to that
as to when i continue going along
so threads in mutex is is is the pretty
you know uh pretty fundamental kind of
concurrency
thing that you do i'm pretty sure most
of you guys know it yesterday
i noticed that most of you are back in
developers so i'm pretty sure you guys
are familiar with
most of these things um but threads in
mutexism i'm sure is probably
pretty pretty something you're pretty
familiar with so
so again how do we deal with like the
atomicity problem right how do we make
sure that data doesn't corrupt it well
use a mutex right use a lock
and um i'm just going to the table on
the top right there you can see so
this uses threads and mutex is kind of
the name of this this pattern
um it uses threads right and it's it's
preemptively scheduled because operating
system threads are promptly
scheduled and it uses shared memory as a
means to communicate
and it does it through locks but with
locks but shared memory is kind of
the method of communication and it's