SlideShare une entreprise Scribd logo
1  sur  148
Télécharger pour lire hors ligne
Thinking Outside
the Synchronisation
Quadrant
@KevlinHenney
Architecture represents the
significant design decisions
that shape a system, where
significant is measured by
cost of change.
Grady Booch
Concurrency
Concurrency
Threads
Concurrency
Threads
Locks
Architecture is the art
of how to waste space.
Philip Johnson
Architecture is the art
of how to waste time.
Mutable
Immutable
Unshared Shared
Unshared mutable
data needs no
synchronisation
Unshared immutable
data needs no
synchronisation
Shared mutable
data needs
synchronisation
Shared immutable
data needs no
synchronisation
Mutable
Immutable
Unshared Shared
Unshared mutable
data needs no
synchronisation
Unshared immutable
data needs no
synchronisation
Shared mutable
data needs
synchronisation
Shared immutable
data needs no
synchronisation
The Synchronisation Quadrant
Systems have properties
— capabilities, features,
characteristics, etc. —
inside and out.
Functional
Operational
Developmental
Functional
Operational
Developmental
This is the monstrosity in love,
lady, that the will is infinite,
and the execution confined;
that the desire is boundless,
and the act a slave to limit.
William Shakespeare
Troilus and Cressida
Multitasking is really just rapid
attention-switching.
And that'd be a useful skill, except it
takes us a second or two to engage
in a new situation we've graced with
our focus.
So, the sum total of attention is
actually decreased as we multitask.
Slicing your attention, in other
words, is less like slicing potatoes
than like slicing plums: you always
lose some juice.
David Weinberger
http://ithare.com/infographics-operation-costs-in-cpu-clock-cycles/
completion time
for single thread
𝑡 = 𝑡1
division of
labour
𝑡 =
𝑡1
𝑛
𝑡 = 𝑡1 1 − 𝑝
𝑛 − 1
𝑛
portion in
parallel
Amdahl's law
𝑡 = 𝑡1 1 − 𝑝
𝑛 − 1
𝑛
+ 𝑘
𝑛 𝑛 − 1
2
typical
communication
overhead
inter-thread
connections
(worst case)
𝑡 = 𝑡1 1 − 𝑝
𝑛 − 1
𝑛
+ 𝑘
𝑛 𝑛 − 1
2
template<typename TaskIterator, typename Reducer>
void map_reduce(
TaskIterator begin, TaskIterator end,
Reducer reduce)
{
std::vector<std::thread> threads;
for(auto task = begin; task != end; ++task)
threads.push_back(std::thread(*task));
for(auto & to_join : threads)
to_join.join();
reduce();
}
Command-line tools
can be 235x faster than
your Hadoop cluster
Adam Drake
http://aadrake.com/command-line-tools-can-be-235x-faster-than-your-hadoop-cluster.html
Functional
Operational
Developmental
A large fraction of the flaws in software development
are due to programmers not fully understanding all
the possible states their code may execute in.
In a multithreaded environment, the lack of
understanding and the resulting problems are greatly
amplified, almost to the point of panic if you are
paying attention.
John Carmack
http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
Some people, when confronted with a
problem, think, "I know, I'll use threads,"
and then two they hav erpoblesms.
Ned Batchelder
https://twitter.com/#!/nedbat/status/194873829825327104
Shared memory is like a canvas where threads
collaborate in painting images, except that
they stand on the opposite sides of the canvas
and use guns rather than brushes.
The only way they can avoid killing each other
is if they shout "duck!" before opening fire.
Bartosz Milewski
"Functional Data Structures and Concurrency in C++"
http://bartoszmilewski.com/2013/12/10/functional-data-structures-and-concurrency-in-c/
There are several ways to
address the problem of
deadlock...
http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
Just ignore it and hope it
doesn't happen.
Ostrich Algorithm
http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
Detection and recovery —
if it happens, take action.
http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
Dynamic avoidance by careful
resource allocation — check to
see if a resource can be
granted, and if granting it will
cause deadlock, don't grant it.
http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
Prevention — change the rules.
http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
Functional
Operational
Developmental
habitable
Habitability is the characteristic
of source code that enables
programmers, coders, bug-fixers,
and people coming to the code
later in its life to understand its
construction and intentions and
to change it comfortably and
confidently.
Habitability makes a place
livable, like home. And this is
what we want in software — that
developers feel at home, can
place their hands on any item
without having to think deeply
about where it is.
testable
Simple Testing Can Prevent
Most Critical Failures
An Analysis of Production Failures in
Distributed Data-Intensive Systems
https://www.usenix.org/system/files/conference/osdi14/osdi14-paper-yuan.pdf
We want our code
to be unit testable.
What is a unit test?
A test is not a unit test if:
▪ It talks to the database
▪ It communicates across the network
▪ It touches the file system
▪ It can't run at the same time as any of your other
unit tests
▪ You have to do special things to your environment
(such as editing config files) to run it.
Michael Feathers
http://www.artima.com/weblogs/viewpost.jsp?thread=126923
A unit test is a test of behaviour
whose success or failure is wholly
determined by the correctness of
the test and the correctness of the
unit under test.
Kevlin Henney
http://www.theregister.co.uk/2007/07/28/what_are_your_units/
What do we want
from unit tests?
When a unit test
passes, it shows
the code is correct.
When a unit test
fails, it shows the
code is incorrect.
isolated
asynchronous
sequential
Future
Immediately return a ‘virtual’ data object—
called a future—to the client when it invokes a
service. This future [...] only provides a value
to clients when the computation is complete.
std::future<ResultType>
iou = std::async(function);
...
ResultType result = iou.get();
joiner<ResultType>
iou = thread(function);
...
ResultType result = iou();
"C++ Threading", ACCU Conference, April 2003
"More C++ Threading", ACCU Conference, April 2004
"N1883: Preliminary Threading Proposal for TR2", JTC1/SC22/WG21, August 2005
immutable
In functional programming, programs are
executed by evaluating expressions, in
contrast with imperative programming where
programs are composed of statements which
change global state when executed.
Functional programming typically avoids
using mutable state.
https://wiki.haskell.org/Functional_programming
Many programming languages support
programming in both functional and
imperative style but the syntax and facilities
of a language are typically optimised for only
one of these styles, and social factors like
coding conventions and libraries often force
the programmer towards one of the styles.
https://wiki.haskell.org/Functional_programming
William Cook, "On Understanding Data Abstraction, Revisited"
[](){}
[](){}()
https://twitter.com/mfeathers/status/29581296216
To keep our C++ API boundary simple, we [...] adopted
one-way data flow. The API consists of methods to
perform fire-and-forget mutations and methods to
compute view models required by specific views.
To keep the code understandable, we write functional
style code converting raw data objects into immutable
view models by default. As we identified performance
bottlenecks through profiling, we added caches to avoid
recomputing unchanged intermediate results.
The resulting functional code is easy to maintain,
without sacrificing performance.
https://code.facebook.com/posts/498597036962415/under-the-hood-building-moments/
Immutable Value
Define a value object type whose instances
are immutable. The internal state of a value
object is set at construction and no
subsequent modifications are allowed.
const
&
&&
Copied Value
Define a value object type whose instances
are copyable. When a value is used in
communication with another thread, ensure
that the value is copied.
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int get_year() const;
int get_month() const;
int get_day_in_month() const;
...
void set_year(int);
void set_month(int);
void set_day_in_month(int);
...
};
Just because you
have a getter,
doesn't mean you
should have a
matching setter.
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int get_year() const;
int get_month() const;
int get_day_in_month() const;
...
void set(int year, int month, int day_in_month);
...
};
today.set(2016, 11, 16);
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int get_year() const;
int get_month() const;
int get_day_in_month() const;
...
};
today = date(2016, 11, 16);
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int get_year() const;
int get_month() const;
int get_day_in_month() const;
...
};
today = date { 2016, 11, 16 };
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int get_year() const;
int get_month() const;
int get_day_in_month() const;
...
};
today = { 2016, 11, 16 };
"Get something"
is an imperative
with an expected
side effect.
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int get_year() const;
int get_month() const;
int get_day_in_month() const;
...
};
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int year() const;
int month() const;
int day_in_month() const;
...
};
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int year() const;
int month() const;
int day_in_month() const;
date with_year(int) const;
...
};
Builder
Introduce a builder that provides separate
methods for constructing and disposing of
each different part of a complex object, or
for combining cumulative changes in the
construction of whole objects.
class date
{
public:
...
int year() const;
int month() const;
int day_in_month() const;
date with_year(int) const;
...
};
class date
{
public:
...
int year() const;
int month() const;
int day_in_month() const;
date with_year(int new_year) const
{
return { new_year, month(), day_in_month() };
}
...
};
class date
{
public:
...
int year() const;
int month() const;
int day_in_month() const;
date with_year(int new_year) const
{
return
new_year == year
? *this
: date { new_year, month(), day_in_month() };
}
...
};
class date
{
public:
...
int year() const;
int month() const;
int day_in_month() const;
date with_year(int) const;
date with_month(int) const;
date with_day_in_month(int) const
...
};
Asking a question
should not change
the answer.
Bertrand Meyer
Asking a question
should not change
the answer, and
nor should asking
it twice!
Referential transparency is a very
desirable property: it implies that
functions consistently yield the same
results given the same input,
irrespective of where and when they are
invoked. That is, function evaluation
depends less—ideally, not at all—on the
side effects of mutable state.
Edward Garson
"Apply Functional Programming Principles"
// "FTL" (Functional Template Library :->)
// container style
template<typename ValueType>
class container
{
public:
typedef const ValueType value_type;
typedef ... iterator;
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
...
container & operator=(const container &);
...
};
template<typename ValueType>
class set
{
public:
typedef const ValueType * iterator;
...
set(std::initializer_list<ValueType> values);
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
iterator find(const ValueType &) const;
std::size_t count(const ValueType &) const;
iterator lower_bound(const ValueType &) const;
iterator upper_bound(const ValueType &) const;
pair<iterator, iterator> equal_range(const ValueType &) const;
...
private:
ValueType * members;
std::size_t cardinality;
};
set<int> c { 2, 9, 9, 7, 9, 2, 4, 5, 8 };
template<typename ValueType>
class array
{
public:
typedef const ValueType * iterator;
...
array(std::initializer_list<ValueType> values);
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & operator[](std::size_t) const;
const ValueType & front() const;
const ValueType & back() const;
const ValueType * data() const;
...
private:
ValueType * elements;
std::size_t length;
};
array<int> c { 2, 9, 9, 7, 9, 2, 4, 5, 8 };
In computing, a persistent data structure is a data structure
that always preserves the previous version of itself when it is
modified. Such data structures are effectively immutable, as
their operations do not (visibly) update the structure in-place,
but instead always yield a new updated structure.
http://en.wikipedia.org/wiki/Persistent_data_structure
(A persistent data structure is not a data structure committed
to persistent storage, such as a disk; this is a different and
unrelated sense of the word "persistent.")
template<typename ValueType>
class vector
{
public:
typedef const ValueType * iterator;
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & operator[](std::size_t) const;
const ValueType & front() const;
const ValueType & back() const;
const ValueType * data() const;
vector pop_front() const;
vector pop_back() const;
...
private:
ValueType * anchor;
iterator from, until;
};
template<typename ValueType>
class vector
{
public:
typedef const ValueType * iterator;
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & operator[](std::size_t) const;
const ValueType & front() const;
const ValueType & back() const;
const ValueType * data() const;
vector pop_front() const;
vector pop_back() const;
...
private:
ValueType * anchor;
iterator from, until;
};
template<typename ValueType>
class vector
{
public:
typedef const ValueType * iterator;
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & operator[](std::size_t) const;
const ValueType & front() const;
const ValueType & back() const;
const ValueType * data() const;
vector popped_front() const;
vector popped_back() const;
...
private:
ValueType * anchor;
iterator from, until;
};
template<typename ValueType>
class vector
{
public:
typedef const ValueType * iterator;
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & operator[](std::size_t) const;
const ValueType & front() const;
const ValueType & back() const;
const ValueType * data() const;
vector popped_front() const;
vector popped_back() const;
...
private:
ValueType * anchor;
iterator from, until;
};
I still have a deep fondness for the
Lisp model. It is simple, elegant, and
something with which all developers
should have an infatuation at least
once in their programming life.
Kevlin Henney
"A Fair Share (Part I)", CUJ C++ Experts Forum, October 2002
lispt
template<typename ValueType>
class list
{
public:
class iterator;
...
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & front() const;
list popped_front() const;
list pushed_front() const;
...
private:
struct link
{
link(const ValueType & value, link * next);
ValueType value;
link * next;
};
link * head;
std::size_t length;
};
Hamlet: Yea, from the table of
my memory I'll wipe away all
trivial fond records.
William Shakespeare
The Tragedy of Hamlet
[Act I, Scene 5]
Garbage collection [...] is optional
in C++; that is, a garbage collector
is not a compulsory part of an
implementation.
Bjarne Stroustrup
http://stroustrup.com/C++11FAQ.html
assert(
std::get_pointer_safety() ==
std::pointer_safety::strict);
Ophelia: 'Tis in my memory
locked, and you yourself shall
keep the key of it.
William Shakespeare
The Tragedy of Hamlet
[Act I, Scene 3]
A use-counted class is more
complicated than a non-use-
counted equivalent, and all of
this horsing around with use
counts takes a significant
amount of processing time.
Robert Murray
C++ Strategies and Tactics
template<typename ValueType>
class vector
{
public:
typedef const ValueType * iterator;
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & operator[](std::size_t) const;
const ValueType & front() const;
const ValueType & back() const;
const ValueType * data() const;
vector popped_front() const;
vector popped_back() const;
...
private:
std::shared_ptr<ValueType> anchor;
iterator from, until;
};
Uses std::default_delete<ValueType[]>, but
cannot be initialised from std::make_shared
template<typename ValueType>
class list
{
public:
class iterator;
...
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & front() const;
list popped_front() const;
list pushed_front() const;
...
private:
struct link
{
link(const ValueType & value, std::shared_ptr<link> next);
ValueType value;
std::shared_ptr<link> next;
};
std::shared_ptr<link> head;
std::size_t length;
};
{
list<Anything> chain;
std::fill_n(
std::front_inserter(chain),
how_many,
something);
}
On destruction, deletion of links is recursive through each link, causing
the stack to blow up for surprisingly small values of how_many.
Instead of using threads and shared
memory as our programming model, we
can use processes and message passing.
Process here just means a protected
independent state with executing code,
not necessarily an operating system
process.
Russel Winder
"Message Passing Leads to Better Scalability in Parallel Systems"
Languages such as Erlang (and occam
before it) have shown that processes are a
very successful mechanism for
programming concurrent and parallel
systems. Such systems do not have all
the synchronization stresses that shared-
memory, multithreaded systems have.
Russel Winder
"Message Passing Leads to Better Scalability in Parallel Systems"
template<typename ValueType>
class channel
{
public:
void send(const ValueType &);
bool try_receive(ValueType &);
private:
...
};
template<typename ValueType>
class channel
{
public:
void send(const ValueType &);
bool try_receive(ValueType &);
private:
std::deque<ValueType> fifo;
};
template<typename ValueType>
class channel
{
public:
void send(const ValueType & to_send)
{
fifo.push_back(to_send);
}
...
};
template<typename ValueType>
class channel
{
public:
...
bool try_receive(ValueType & to_receive)
{
bool received = false;
if (!fifo.empty())
{
to_receive = fifo.front();
fifo.pop_front();
received = true;
}
return received;
}
...
};
template<typename ValueType>
class channel
{
public:
void send(const ValueType &);
bool try_receive(ValueType &);
private:
std::mutex key;
std::deque<ValueType> fifo;
};
void send(const ValueType & to_send)
{
std::lock_guard<std::mutex> guard(key);
fifo.push_back(to_send);
}
bool try_receive(ValueType & to_receive)
{
bool received = false;
if (key.try_lock())
{
std::lock_guard<std::mutex> guard(key, std::adopt_lock);
if (!fifo.empty())
{
to_receive = fifo.front();
fifo.pop_front();
received = true;
}
}
return received;
}
template<typename ValueType>
class channel
{
public:
void send(const ValueType &);
void receive(ValueType &);
bool try_receive(ValueType &);
private:
std::mutex key;
std::condition_variable_any non_empty;
std::deque<ValueType> fifo;
};
void send(const ValueType & to_send)
{
std::lock_guard<std::mutex> guard(key);
fifo.push_back(to_send);
non_empty.notify_all();
}
void receive(ValueType & to_receive)
{
std::lock_guard<std::mutex> guard(key);
non_empty.wait(
key,
[this]
{
return !fifo.empty();
});
to_receive = fifo.front();
fifo.pop_front();
}
https://twitter.com/richardadalton/status/591534529086693376
std::string fizzbuzz(int n)
{
return
n % 15 == 0 ? "FizzBuzz" :
n % 3 == 0 ? "Fizz" :
n % 5 == 0 ? "Buzz" :
std::to_string(n);
}
void fizzbuzzer(channel<int> & in, channel<std::string> & out)
{
for (;;)
{
int n;
in.receive(n);
out.send(fizzbuzz(n));
}
}
int main()
{
channel<int> out;
channel<std::string> back;
std::thread fizzbuzzing(fizzbuzzer, out, back)
for (int n = 1; n <= 100; ++n)
{
out.send(n);
std::string result;
back.receive(result);
std::cout << result << "n";
}
...
}
int main()
{
channel<int> out;
channel<std::string> back;
std::thread fizzbuzzing(fizzbuzzer, out, back)
for (int n = 1; n <= 100; ++n)
{
out << n;
std::string result;
back >> result;
std::cout << result << "n";
}
...
}
void fizzbuzzer(channel<int> & in, channel<std::string> & out)
{
for (;;)
{
int n;
in >> n;
out << fizzbuzz(n);
}
}
template<typename ValueType>
class channel
{
public:
void send(const ValueType &);
void receive(ValueType &);
bool try_receive(ValueType &);
void operator<<(const ValueType &);
void operator>>(ValueType &);
private:
std::mutex key;
std::condition_variable_any non_empty;
std::deque<ValueType> fifo;
};
template<typename ValueType>
class channel
{
public:
void send(const ValueType &);
void receive(ValueType &);
bool try_receive(ValueType &);
void operator<<(const ValueType &);
receiving operator>>(ValueType &);
private:
std::mutex key;
std::condition_variable_any non_empty;
std::deque<ValueType> fifo;
};
template<typename ValueType>
class channel
{
public:
void send(const ValueType &);
void receive(ValueType &);
bool try_receive(ValueType &);
void operator<<(const ValueType & to_send)
{
send(to_send);
}
receiving operator>>(ValueType & to_receive);
{
return receiving(this, to_receive);
}
...
};
class receiving
{
public:
receiving(channel * that, ValueType & to_receive)
: that(that), to_receive(to_receive)
{
}
receiving(receiving && other)
: that(other.that), to_receive(other.to_receive)
{
other.that = nullptr;
}
operator bool()
{
auto from = that;
that = nullptr;
return from && from->try_receive(to_receive);
}
~receiving()
{
if (that)
that->receive(to_receive);
}
private:
channel * that;
ValueType & to_receive;
};
std::string fizzbuzz(int n)
{
if (n < 1 || n > 100)
throw std::domain_error(
"fizzbuzz(n) is defined for n in [1..100]")
return
n % 15 == 0 ? "FizzBuzz" :
n % 3 == 0 ? "Fizz" :
n % 5 == 0 ? "Buzz" :
std::to_string(n);
}
void fizzbuzzer(channel<int> & in, channel<std::any> & out)
{
for (;;)
{
try
{
int n;
in >> n;
out << fizzbuzz(n);
}
catch (...)
{
out << std::current_exception();
}
}
}
int main()
{
channel<int> out;
channel<std::any> back;
std::thread fizzbuzzing(fizzbuzzer, out, back)
for (int n = 1; n <= 100; ++n)
{
out << n;
std::any result;
back >> result;
if (result.type() == typeid(std::string))
std::cout << std::any_cast<std::string>(result) << "n";
}
...
}
template<typename ValueType>
class channel
{
public:
channel();
channel(std::function<void(const ValueType &)>);
void send(const ValueType &);
void receive(ValueType &);
bool try_receive(ValueType &);
void operator<<(const ValueType &);
receiving operator>>(ValueType &);
private:
std::mutex key;
std::condition_variable_any non_empty;
std::deque<ValueType> fifo;
};
int main()
{
channel<int> out;
channel<std::any> back(
[](const any & received)
{
if (received.type() == typeid(std::exception_ptr))
std::rethrow_exception(any_cast<std::exception_ptr>(received));
});
std::thread fizzbuzzing(fizzbuzzer, out, back)
...
}
int main()
{
...
for (int n = 1; n <= 100; ++n)
{
try
{
out << n;
std::any result;
back >> result;
std::cout << std::any_cast<std::string>(result) << "n";
}
catch (std::domain_error & caught)
{
std::cout << caught.what() << "n";
}
}
...
}
Pipes and Filters
Divide the application's task into
several self-contained data
processing steps and connect these
steps to a data processing pipeline
via intermediate data buffers.
Simple filters that can be arbitrarily
chained are more easily re-used, and
more robust, than almost any other
kind of code.
Brandon Rhodes
http://rhodesmill.org/brandon/slides/2012-11-pyconca/
Multithreading is just one
damn thing after, before, or
simultaneous with another.
Andrei Alexandrescu
Actor-based concurrency is
just one damn message after
another.
No matter what language you work in,
programming in a functional style provides
benefits.
You should do it whenever it is convenient,
and you should think hard about the
decision when it isn't convenient.
John Carmack
http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
Programming in a functional style makes
the state presented to your code explicit,
which makes it much easier to reason
about, and, in a completely pure system,
makes thread race conditions impossible.
John Carmack
http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
Think outside the
synchronisation
quadrant...
All computers
wait at the
same speed.

Contenu connexe

Tendances

Digital Transformation Toolkit - Overview and Approach
Digital Transformation Toolkit - Overview and ApproachDigital Transformation Toolkit - Overview and Approach
Digital Transformation Toolkit - Overview and ApproachPeterFranz6
 
Making the matrix work
Making the matrix workMaking the matrix work
Making the matrix workGMR Group
 
Digital Transformation & Cloud Profitability
Digital Transformation & Cloud ProfitabilityDigital Transformation & Cloud Profitability
Digital Transformation & Cloud ProfitabilityGui Carvalhal
 
Integration: The $100 Billion Opportunity No One Wants to Talk About
Integration: The $100 Billion Opportunity No One Wants to Talk AboutIntegration: The $100 Billion Opportunity No One Wants to Talk About
Integration: The $100 Billion Opportunity No One Wants to Talk AboutBramh Gupta
 
Monoliths, microservices, and team cognitive load - Team Topologies - DOES EU...
Monoliths, microservices, and team cognitive load - Team Topologies - DOES EU...Monoliths, microservices, and team cognitive load - Team Topologies - DOES EU...
Monoliths, microservices, and team cognitive load - Team Topologies - DOES EU...Matthew Skelton
 
Continuous Delivery at scale - Matthew Skelton - NHS Digital agile CoP - Marc...
Continuous Delivery at scale - Matthew Skelton - NHS Digital agile CoP - Marc...Continuous Delivery at scale - Matthew Skelton - NHS Digital agile CoP - Marc...
Continuous Delivery at scale - Matthew Skelton - NHS Digital agile CoP - Marc...Matthew Skelton
 
De la gestion de portefeuille Lean à la gestion des flux de valeur avec le Fl...
De la gestion de portefeuille Lean à la gestion des flux de valeur avec le Fl...De la gestion de portefeuille Lean à la gestion des flux de valeur avec le Fl...
De la gestion de portefeuille Lean à la gestion des flux de valeur avec le Fl...Agile En Seine
 
Uncover your-potential
Uncover your-potentialUncover your-potential
Uncover your-potentialAbdon Kanuti
 
Composale DXP with MACH architecture.pptx
Composale DXP with MACH architecture.pptxComposale DXP with MACH architecture.pptx
Composale DXP with MACH architecture.pptxPieter Brinkman
 
The Types of TPM Roles by Facebook Product Leader
The Types of TPM Roles by Facebook Product LeaderThe Types of TPM Roles by Facebook Product Leader
The Types of TPM Roles by Facebook Product LeaderProduct School
 
Why, When and How Do I Start a Digital Transformation?
Why, When and How Do I Start a Digital Transformation?Why, When and How Do I Start a Digital Transformation?
Why, When and How Do I Start a Digital Transformation?Acquia
 
Complexity Thinking
Complexity ThinkingComplexity Thinking
Complexity ThinkingSander Schot
 
Building Digital Strategy Roadmap For Digital Transformation Complete Deck
Building Digital Strategy Roadmap For Digital Transformation Complete DeckBuilding Digital Strategy Roadmap For Digital Transformation Complete Deck
Building Digital Strategy Roadmap For Digital Transformation Complete DeckSlideTeam
 
Digital Workplace Roadmap
Digital Workplace RoadmapDigital Workplace Roadmap
Digital Workplace RoadmapSam Marshall
 
Eliminate the Blind Spots in Your ServiceNow Discovery Environment
Eliminate the Blind Spots in Your ServiceNow Discovery EnvironmentEliminate the Blind Spots in Your ServiceNow Discovery Environment
Eliminate the Blind Spots in Your ServiceNow Discovery EnvironmentPrecisely
 
Applied Domain-Driven Design Blueprints for Jakarta EE
Applied Domain-Driven Design Blueprints for Jakarta EEApplied Domain-Driven Design Blueprints for Jakarta EE
Applied Domain-Driven Design Blueprints for Jakarta EEJakarta_EE
 
微服務的基礎建設 - Service Discovery, Andrew Wu
微服務的基礎建設 - Service Discovery, Andrew Wu微服務的基礎建設 - Service Discovery, Andrew Wu
微服務的基礎建設 - Service Discovery, Andrew WuAndrew Wu
 

Tendances (20)

Digital Transformation Toolkit - Overview and Approach
Digital Transformation Toolkit - Overview and ApproachDigital Transformation Toolkit - Overview and Approach
Digital Transformation Toolkit - Overview and Approach
 
Making the matrix work
Making the matrix workMaking the matrix work
Making the matrix work
 
Digital Transformation & Cloud Profitability
Digital Transformation & Cloud ProfitabilityDigital Transformation & Cloud Profitability
Digital Transformation & Cloud Profitability
 
How Great Companies Get Their Mojo from Maslow
How Great Companies Get Their Mojo from MaslowHow Great Companies Get Their Mojo from Maslow
How Great Companies Get Their Mojo from Maslow
 
Integration: The $100 Billion Opportunity No One Wants to Talk About
Integration: The $100 Billion Opportunity No One Wants to Talk AboutIntegration: The $100 Billion Opportunity No One Wants to Talk About
Integration: The $100 Billion Opportunity No One Wants to Talk About
 
Monoliths, microservices, and team cognitive load - Team Topologies - DOES EU...
Monoliths, microservices, and team cognitive load - Team Topologies - DOES EU...Monoliths, microservices, and team cognitive load - Team Topologies - DOES EU...
Monoliths, microservices, and team cognitive load - Team Topologies - DOES EU...
 
Continuous Delivery at scale - Matthew Skelton - NHS Digital agile CoP - Marc...
Continuous Delivery at scale - Matthew Skelton - NHS Digital agile CoP - Marc...Continuous Delivery at scale - Matthew Skelton - NHS Digital agile CoP - Marc...
Continuous Delivery at scale - Matthew Skelton - NHS Digital agile CoP - Marc...
 
De la gestion de portefeuille Lean à la gestion des flux de valeur avec le Fl...
De la gestion de portefeuille Lean à la gestion des flux de valeur avec le Fl...De la gestion de portefeuille Lean à la gestion des flux de valeur avec le Fl...
De la gestion de portefeuille Lean à la gestion des flux de valeur avec le Fl...
 
Uncover your-potential
Uncover your-potentialUncover your-potential
Uncover your-potential
 
Composale DXP with MACH architecture.pptx
Composale DXP with MACH architecture.pptxComposale DXP with MACH architecture.pptx
Composale DXP with MACH architecture.pptx
 
Digital Transformation: Step-by-step Implementation Guide
Digital Transformation: Step-by-step Implementation GuideDigital Transformation: Step-by-step Implementation Guide
Digital Transformation: Step-by-step Implementation Guide
 
The Types of TPM Roles by Facebook Product Leader
The Types of TPM Roles by Facebook Product LeaderThe Types of TPM Roles by Facebook Product Leader
The Types of TPM Roles by Facebook Product Leader
 
Antifragile
AntifragileAntifragile
Antifragile
 
Why, When and How Do I Start a Digital Transformation?
Why, When and How Do I Start a Digital Transformation?Why, When and How Do I Start a Digital Transformation?
Why, When and How Do I Start a Digital Transformation?
 
Complexity Thinking
Complexity ThinkingComplexity Thinking
Complexity Thinking
 
Building Digital Strategy Roadmap For Digital Transformation Complete Deck
Building Digital Strategy Roadmap For Digital Transformation Complete DeckBuilding Digital Strategy Roadmap For Digital Transformation Complete Deck
Building Digital Strategy Roadmap For Digital Transformation Complete Deck
 
Digital Workplace Roadmap
Digital Workplace RoadmapDigital Workplace Roadmap
Digital Workplace Roadmap
 
Eliminate the Blind Spots in Your ServiceNow Discovery Environment
Eliminate the Blind Spots in Your ServiceNow Discovery EnvironmentEliminate the Blind Spots in Your ServiceNow Discovery Environment
Eliminate the Blind Spots in Your ServiceNow Discovery Environment
 
Applied Domain-Driven Design Blueprints for Jakarta EE
Applied Domain-Driven Design Blueprints for Jakarta EEApplied Domain-Driven Design Blueprints for Jakarta EE
Applied Domain-Driven Design Blueprints for Jakarta EE
 
微服務的基礎建設 - Service Discovery, Andrew Wu
微服務的基礎建設 - Service Discovery, Andrew Wu微服務的基礎建設 - Service Discovery, Andrew Wu
微服務的基礎建設 - Service Discovery, Andrew Wu
 

Similaire à Thinking Outside the Synchronisation Quadrant

Patterns for the People
Patterns for the PeoplePatterns for the People
Patterns for the PeopleKevlin Henney
 
Java Programming
Java ProgrammingJava Programming
Java ProgrammingTracy Clark
 
Design patterns in javascript
Design patterns in javascriptDesign patterns in javascript
Design patterns in javascriptAyush Sharma
 
The Theory Of The Dom
The Theory Of The DomThe Theory Of The Dom
The Theory Of The Domkaven yan
 
C questions
C questionsC questions
C questionsparm112
 
Models vs Reality: Quest for the Roots of Complexity
Models vs Reality: Quest for the Roots of ComplexityModels vs Reality: Quest for the Roots of Complexity
Models vs Reality: Quest for the Roots of ComplexityJulian Warszawski
 
P Training Presentation
P Training PresentationP Training Presentation
P Training PresentationGaurav Tyagi
 
Singleton Design Pattern - Creation Pattern
Singleton Design Pattern - Creation PatternSingleton Design Pattern - Creation Pattern
Singleton Design Pattern - Creation PatternSeerat Malik
 
cf.Objective() 2017 - Design patterns - Brad Wood
cf.Objective() 2017 - Design patterns - Brad Woodcf.Objective() 2017 - Design patterns - Brad Wood
cf.Objective() 2017 - Design patterns - Brad WoodOrtus Solutions, Corp
 
New microsoft office word document (2)
New microsoft office word document (2)New microsoft office word document (2)
New microsoft office word document (2)rashmita_mishra
 
Design Pattern For C# Part 1
Design Pattern For C# Part 1Design Pattern For C# Part 1
Design Pattern For C# Part 1Shahzad
 
Neal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary ArchitectureNeal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary ArchitectureThoughtWorks Studios
 
Neal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary ArchitectureNeal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary ArchitectureThoughtworks
 
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)Ovidiu Farauanu
 
10 ways to make your code rock
10 ways to make your code rock10 ways to make your code rock
10 ways to make your code rockmartincronje
 
Dot Net Accenture
Dot Net AccentureDot Net Accenture
Dot Net AccentureSri K
 

Similaire à Thinking Outside the Synchronisation Quadrant (20)

Patterns for the People
Patterns for the PeoplePatterns for the People
Patterns for the People
 
Java Programming
Java ProgrammingJava Programming
Java Programming
 
Design patterns in javascript
Design patterns in javascriptDesign patterns in javascript
Design patterns in javascript
 
The Theory Of The Dom
The Theory Of The DomThe Theory Of The Dom
The Theory Of The Dom
 
C questions
C questionsC questions
C questions
 
Models vs Reality: Quest for the Roots of Complexity
Models vs Reality: Quest for the Roots of ComplexityModels vs Reality: Quest for the Roots of Complexity
Models vs Reality: Quest for the Roots of Complexity
 
P Training Presentation
P Training PresentationP Training Presentation
P Training Presentation
 
Oopp Lab Work
Oopp Lab WorkOopp Lab Work
Oopp Lab Work
 
Singleton Design Pattern - Creation Pattern
Singleton Design Pattern - Creation PatternSingleton Design Pattern - Creation Pattern
Singleton Design Pattern - Creation Pattern
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
cf.Objective() 2017 - Design patterns - Brad Wood
cf.Objective() 2017 - Design patterns - Brad Woodcf.Objective() 2017 - Design patterns - Brad Wood
cf.Objective() 2017 - Design patterns - Brad Wood
 
Design Patterns
Design PatternsDesign Patterns
Design Patterns
 
Effective Java
Effective JavaEffective Java
Effective Java
 
New microsoft office word document (2)
New microsoft office word document (2)New microsoft office word document (2)
New microsoft office word document (2)
 
Design Pattern For C# Part 1
Design Pattern For C# Part 1Design Pattern For C# Part 1
Design Pattern For C# Part 1
 
Neal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary ArchitectureNeal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary Architecture
 
Neal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary ArchitectureNeal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary Architecture
 
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
 
10 ways to make your code rock
10 ways to make your code rock10 ways to make your code rock
10 ways to make your code rock
 
Dot Net Accenture
Dot Net AccentureDot Net Accenture
Dot Net Accenture
 

Plus de Kevlin Henney

The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical ExcellenceKevlin Henney
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical DevelopmentKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid DeconstructionKevlin Henney
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayKevlin Henney
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test CasesKevlin Henney
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to ImmutabilityKevlin Henney
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-InKevlin Henney
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good NameKevlin Henney
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Kevlin Henney
 
The Error of Our Ways
The Error of Our WaysThe Error of Our Ways
The Error of Our WaysKevlin Henney
 

Plus de Kevlin Henney (20)

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
 
Get Kata
Get KataGet Kata
Get Kata
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
 
Good Code
Good CodeGood Code
Good Code
 
The Error of Our Ways
The Error of Our WaysThe Error of Our Ways
The Error of Our Ways
 

Dernier

Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfryanfarris8
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 

Dernier (20)

Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 

Thinking Outside the Synchronisation Quadrant

  • 2.
  • 3.
  • 4.
  • 5. Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change. Grady Booch
  • 9. Architecture is the art of how to waste space. Philip Johnson
  • 10. Architecture is the art of how to waste time.
  • 11. Mutable Immutable Unshared Shared Unshared mutable data needs no synchronisation Unshared immutable data needs no synchronisation Shared mutable data needs synchronisation Shared immutable data needs no synchronisation
  • 12. Mutable Immutable Unshared Shared Unshared mutable data needs no synchronisation Unshared immutable data needs no synchronisation Shared mutable data needs synchronisation Shared immutable data needs no synchronisation The Synchronisation Quadrant
  • 13. Systems have properties — capabilities, features, characteristics, etc. — inside and out.
  • 14.
  • 17. This is the monstrosity in love, lady, that the will is infinite, and the execution confined; that the desire is boundless, and the act a slave to limit. William Shakespeare Troilus and Cressida
  • 18. Multitasking is really just rapid attention-switching. And that'd be a useful skill, except it takes us a second or two to engage in a new situation we've graced with our focus. So, the sum total of attention is actually decreased as we multitask. Slicing your attention, in other words, is less like slicing potatoes than like slicing plums: you always lose some juice. David Weinberger
  • 20. completion time for single thread 𝑡 = 𝑡1
  • 22. 𝑡 = 𝑡1 1 − 𝑝 𝑛 − 1 𝑛 portion in parallel Amdahl's law
  • 23. 𝑡 = 𝑡1 1 − 𝑝 𝑛 − 1 𝑛 + 𝑘 𝑛 𝑛 − 1 2 typical communication overhead inter-thread connections (worst case)
  • 24. 𝑡 = 𝑡1 1 − 𝑝 𝑛 − 1 𝑛 + 𝑘 𝑛 𝑛 − 1 2
  • 25. template<typename TaskIterator, typename Reducer> void map_reduce( TaskIterator begin, TaskIterator end, Reducer reduce) { std::vector<std::thread> threads; for(auto task = begin; task != end; ++task) threads.push_back(std::thread(*task)); for(auto & to_join : threads) to_join.join(); reduce(); }
  • 26. Command-line tools can be 235x faster than your Hadoop cluster Adam Drake http://aadrake.com/command-line-tools-can-be-235x-faster-than-your-hadoop-cluster.html
  • 28. A large fraction of the flaws in software development are due to programmers not fully understanding all the possible states their code may execute in. In a multithreaded environment, the lack of understanding and the resulting problems are greatly amplified, almost to the point of panic if you are paying attention. John Carmack http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
  • 29. Some people, when confronted with a problem, think, "I know, I'll use threads," and then two they hav erpoblesms. Ned Batchelder https://twitter.com/#!/nedbat/status/194873829825327104
  • 30. Shared memory is like a canvas where threads collaborate in painting images, except that they stand on the opposite sides of the canvas and use guns rather than brushes. The only way they can avoid killing each other is if they shout "duck!" before opening fire. Bartosz Milewski "Functional Data Structures and Concurrency in C++" http://bartoszmilewski.com/2013/12/10/functional-data-structures-and-concurrency-in-c/
  • 31. There are several ways to address the problem of deadlock... http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
  • 32. Just ignore it and hope it doesn't happen. Ostrich Algorithm http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
  • 33. Detection and recovery — if it happens, take action. http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
  • 34. Dynamic avoidance by careful resource allocation — check to see if a resource can be granted, and if granting it will cause deadlock, don't grant it. http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
  • 35. Prevention — change the rules. http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
  • 38.
  • 39. Habitability is the characteristic of source code that enables programmers, coders, bug-fixers, and people coming to the code later in its life to understand its construction and intentions and to change it comfortably and confidently.
  • 40. Habitability makes a place livable, like home. And this is what we want in software — that developers feel at home, can place their hands on any item without having to think deeply about where it is.
  • 42. Simple Testing Can Prevent Most Critical Failures An Analysis of Production Failures in Distributed Data-Intensive Systems https://www.usenix.org/system/files/conference/osdi14/osdi14-paper-yuan.pdf
  • 43. We want our code to be unit testable. What is a unit test?
  • 44. A test is not a unit test if: ▪ It talks to the database ▪ It communicates across the network ▪ It touches the file system ▪ It can't run at the same time as any of your other unit tests ▪ You have to do special things to your environment (such as editing config files) to run it. Michael Feathers http://www.artima.com/weblogs/viewpost.jsp?thread=126923
  • 45. A unit test is a test of behaviour whose success or failure is wholly determined by the correctness of the test and the correctness of the unit under test. Kevlin Henney http://www.theregister.co.uk/2007/07/28/what_are_your_units/
  • 46. What do we want from unit tests?
  • 47. When a unit test passes, it shows the code is correct.
  • 48. When a unit test fails, it shows the code is incorrect.
  • 52.
  • 53. Future Immediately return a ‘virtual’ data object— called a future—to the client when it invokes a service. This future [...] only provides a value to clients when the computation is complete.
  • 55. joiner<ResultType> iou = thread(function); ... ResultType result = iou(); "C++ Threading", ACCU Conference, April 2003 "More C++ Threading", ACCU Conference, April 2004 "N1883: Preliminary Threading Proposal for TR2", JTC1/SC22/WG21, August 2005
  • 57. In functional programming, programs are executed by evaluating expressions, in contrast with imperative programming where programs are composed of statements which change global state when executed. Functional programming typically avoids using mutable state. https://wiki.haskell.org/Functional_programming
  • 58. Many programming languages support programming in both functional and imperative style but the syntax and facilities of a language are typically optimised for only one of these styles, and social factors like coding conventions and libraries often force the programmer towards one of the styles. https://wiki.haskell.org/Functional_programming
  • 59. William Cook, "On Understanding Data Abstraction, Revisited"
  • 63. To keep our C++ API boundary simple, we [...] adopted one-way data flow. The API consists of methods to perform fire-and-forget mutations and methods to compute view models required by specific views. To keep the code understandable, we write functional style code converting raw data objects into immutable view models by default. As we identified performance bottlenecks through profiling, we added caches to avoid recomputing unchanged intermediate results. The resulting functional code is easy to maintain, without sacrificing performance. https://code.facebook.com/posts/498597036962415/under-the-hood-building-moments/
  • 64. Immutable Value Define a value object type whose instances are immutable. The internal state of a value object is set at construction and no subsequent modifications are allowed.
  • 65. const
  • 66. &
  • 67. &&
  • 68. Copied Value Define a value object type whose instances are copyable. When a value is used in communication with another thread, ensure that the value is copied.
  • 69. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int get_year() const; int get_month() const; int get_day_in_month() const; ... void set_year(int); void set_month(int); void set_day_in_month(int); ... };
  • 70. Just because you have a getter, doesn't mean you should have a matching setter.
  • 71. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int get_year() const; int get_month() const; int get_day_in_month() const; ... void set(int year, int month, int day_in_month); ... }; today.set(2016, 11, 16);
  • 72. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int get_year() const; int get_month() const; int get_day_in_month() const; ... }; today = date(2016, 11, 16);
  • 73. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int get_year() const; int get_month() const; int get_day_in_month() const; ... }; today = date { 2016, 11, 16 };
  • 74. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int get_year() const; int get_month() const; int get_day_in_month() const; ... }; today = { 2016, 11, 16 };
  • 75. "Get something" is an imperative with an expected side effect.
  • 76. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int get_year() const; int get_month() const; int get_day_in_month() const; ... };
  • 77. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int year() const; int month() const; int day_in_month() const; ... };
  • 78. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int year() const; int month() const; int day_in_month() const; date with_year(int) const; ... };
  • 79. Builder Introduce a builder that provides separate methods for constructing and disposing of each different part of a complex object, or for combining cumulative changes in the construction of whole objects.
  • 80. class date { public: ... int year() const; int month() const; int day_in_month() const; date with_year(int) const; ... };
  • 81. class date { public: ... int year() const; int month() const; int day_in_month() const; date with_year(int new_year) const { return { new_year, month(), day_in_month() }; } ... };
  • 82. class date { public: ... int year() const; int month() const; int day_in_month() const; date with_year(int new_year) const { return new_year == year ? *this : date { new_year, month(), day_in_month() }; } ... };
  • 83. class date { public: ... int year() const; int month() const; int day_in_month() const; date with_year(int) const; date with_month(int) const; date with_day_in_month(int) const ... };
  • 84. Asking a question should not change the answer. Bertrand Meyer
  • 85. Asking a question should not change the answer, and nor should asking it twice!
  • 86. Referential transparency is a very desirable property: it implies that functions consistently yield the same results given the same input, irrespective of where and when they are invoked. That is, function evaluation depends less—ideally, not at all—on the side effects of mutable state. Edward Garson "Apply Functional Programming Principles"
  • 87. // "FTL" (Functional Template Library :->) // container style template<typename ValueType> class container { public: typedef const ValueType value_type; typedef ... iterator; ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; ... container & operator=(const container &); ... };
  • 88. template<typename ValueType> class set { public: typedef const ValueType * iterator; ... set(std::initializer_list<ValueType> values); ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; iterator find(const ValueType &) const; std::size_t count(const ValueType &) const; iterator lower_bound(const ValueType &) const; iterator upper_bound(const ValueType &) const; pair<iterator, iterator> equal_range(const ValueType &) const; ... private: ValueType * members; std::size_t cardinality; }; set<int> c { 2, 9, 9, 7, 9, 2, 4, 5, 8 };
  • 89. template<typename ValueType> class array { public: typedef const ValueType * iterator; ... array(std::initializer_list<ValueType> values); ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & operator[](std::size_t) const; const ValueType & front() const; const ValueType & back() const; const ValueType * data() const; ... private: ValueType * elements; std::size_t length; }; array<int> c { 2, 9, 9, 7, 9, 2, 4, 5, 8 };
  • 90. In computing, a persistent data structure is a data structure that always preserves the previous version of itself when it is modified. Such data structures are effectively immutable, as their operations do not (visibly) update the structure in-place, but instead always yield a new updated structure. http://en.wikipedia.org/wiki/Persistent_data_structure (A persistent data structure is not a data structure committed to persistent storage, such as a disk; this is a different and unrelated sense of the word "persistent.")
  • 91.
  • 92.
  • 93.
  • 94.
  • 95. template<typename ValueType> class vector { public: typedef const ValueType * iterator; ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & operator[](std::size_t) const; const ValueType & front() const; const ValueType & back() const; const ValueType * data() const; vector pop_front() const; vector pop_back() const; ... private: ValueType * anchor; iterator from, until; };
  • 96. template<typename ValueType> class vector { public: typedef const ValueType * iterator; ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & operator[](std::size_t) const; const ValueType & front() const; const ValueType & back() const; const ValueType * data() const; vector pop_front() const; vector pop_back() const; ... private: ValueType * anchor; iterator from, until; };
  • 97. template<typename ValueType> class vector { public: typedef const ValueType * iterator; ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & operator[](std::size_t) const; const ValueType & front() const; const ValueType & back() const; const ValueType * data() const; vector popped_front() const; vector popped_back() const; ... private: ValueType * anchor; iterator from, until; };
  • 98. template<typename ValueType> class vector { public: typedef const ValueType * iterator; ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & operator[](std::size_t) const; const ValueType & front() const; const ValueType & back() const; const ValueType * data() const; vector popped_front() const; vector popped_back() const; ... private: ValueType * anchor; iterator from, until; };
  • 99.
  • 100. I still have a deep fondness for the Lisp model. It is simple, elegant, and something with which all developers should have an infatuation at least once in their programming life. Kevlin Henney "A Fair Share (Part I)", CUJ C++ Experts Forum, October 2002
  • 101. lispt
  • 102. template<typename ValueType> class list { public: class iterator; ... std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & front() const; list popped_front() const; list pushed_front() const; ... private: struct link { link(const ValueType & value, link * next); ValueType value; link * next; }; link * head; std::size_t length; };
  • 103. Hamlet: Yea, from the table of my memory I'll wipe away all trivial fond records. William Shakespeare The Tragedy of Hamlet [Act I, Scene 5]
  • 104. Garbage collection [...] is optional in C++; that is, a garbage collector is not a compulsory part of an implementation. Bjarne Stroustrup http://stroustrup.com/C++11FAQ.html
  • 106. Ophelia: 'Tis in my memory locked, and you yourself shall keep the key of it. William Shakespeare The Tragedy of Hamlet [Act I, Scene 3]
  • 107. A use-counted class is more complicated than a non-use- counted equivalent, and all of this horsing around with use counts takes a significant amount of processing time. Robert Murray C++ Strategies and Tactics
  • 108. template<typename ValueType> class vector { public: typedef const ValueType * iterator; ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & operator[](std::size_t) const; const ValueType & front() const; const ValueType & back() const; const ValueType * data() const; vector popped_front() const; vector popped_back() const; ... private: std::shared_ptr<ValueType> anchor; iterator from, until; }; Uses std::default_delete<ValueType[]>, but cannot be initialised from std::make_shared
  • 109. template<typename ValueType> class list { public: class iterator; ... std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & front() const; list popped_front() const; list pushed_front() const; ... private: struct link { link(const ValueType & value, std::shared_ptr<link> next); ValueType value; std::shared_ptr<link> next; }; std::shared_ptr<link> head; std::size_t length; };
  • 110. { list<Anything> chain; std::fill_n( std::front_inserter(chain), how_many, something); } On destruction, deletion of links is recursive through each link, causing the stack to blow up for surprisingly small values of how_many.
  • 111. Instead of using threads and shared memory as our programming model, we can use processes and message passing. Process here just means a protected independent state with executing code, not necessarily an operating system process. Russel Winder "Message Passing Leads to Better Scalability in Parallel Systems"
  • 112. Languages such as Erlang (and occam before it) have shown that processes are a very successful mechanism for programming concurrent and parallel systems. Such systems do not have all the synchronization stresses that shared- memory, multithreaded systems have. Russel Winder "Message Passing Leads to Better Scalability in Parallel Systems"
  • 113.
  • 114. template<typename ValueType> class channel { public: void send(const ValueType &); bool try_receive(ValueType &); private: ... };
  • 115. template<typename ValueType> class channel { public: void send(const ValueType &); bool try_receive(ValueType &); private: std::deque<ValueType> fifo; };
  • 116. template<typename ValueType> class channel { public: void send(const ValueType & to_send) { fifo.push_back(to_send); } ... };
  • 117. template<typename ValueType> class channel { public: ... bool try_receive(ValueType & to_receive) { bool received = false; if (!fifo.empty()) { to_receive = fifo.front(); fifo.pop_front(); received = true; } return received; } ... };
  • 118. template<typename ValueType> class channel { public: void send(const ValueType &); bool try_receive(ValueType &); private: std::mutex key; std::deque<ValueType> fifo; };
  • 119. void send(const ValueType & to_send) { std::lock_guard<std::mutex> guard(key); fifo.push_back(to_send); }
  • 120. bool try_receive(ValueType & to_receive) { bool received = false; if (key.try_lock()) { std::lock_guard<std::mutex> guard(key, std::adopt_lock); if (!fifo.empty()) { to_receive = fifo.front(); fifo.pop_front(); received = true; } } return received; }
  • 121. template<typename ValueType> class channel { public: void send(const ValueType &); void receive(ValueType &); bool try_receive(ValueType &); private: std::mutex key; std::condition_variable_any non_empty; std::deque<ValueType> fifo; };
  • 122. void send(const ValueType & to_send) { std::lock_guard<std::mutex> guard(key); fifo.push_back(to_send); non_empty.notify_all(); }
  • 123. void receive(ValueType & to_receive) { std::lock_guard<std::mutex> guard(key); non_empty.wait( key, [this] { return !fifo.empty(); }); to_receive = fifo.front(); fifo.pop_front(); }
  • 125. std::string fizzbuzz(int n) { return n % 15 == 0 ? "FizzBuzz" : n % 3 == 0 ? "Fizz" : n % 5 == 0 ? "Buzz" : std::to_string(n); }
  • 126. void fizzbuzzer(channel<int> & in, channel<std::string> & out) { for (;;) { int n; in.receive(n); out.send(fizzbuzz(n)); } }
  • 127. int main() { channel<int> out; channel<std::string> back; std::thread fizzbuzzing(fizzbuzzer, out, back) for (int n = 1; n <= 100; ++n) { out.send(n); std::string result; back.receive(result); std::cout << result << "n"; } ... }
  • 128. int main() { channel<int> out; channel<std::string> back; std::thread fizzbuzzing(fizzbuzzer, out, back) for (int n = 1; n <= 100; ++n) { out << n; std::string result; back >> result; std::cout << result << "n"; } ... }
  • 129. void fizzbuzzer(channel<int> & in, channel<std::string> & out) { for (;;) { int n; in >> n; out << fizzbuzz(n); } }
  • 130. template<typename ValueType> class channel { public: void send(const ValueType &); void receive(ValueType &); bool try_receive(ValueType &); void operator<<(const ValueType &); void operator>>(ValueType &); private: std::mutex key; std::condition_variable_any non_empty; std::deque<ValueType> fifo; };
  • 131. template<typename ValueType> class channel { public: void send(const ValueType &); void receive(ValueType &); bool try_receive(ValueType &); void operator<<(const ValueType &); receiving operator>>(ValueType &); private: std::mutex key; std::condition_variable_any non_empty; std::deque<ValueType> fifo; };
  • 132. template<typename ValueType> class channel { public: void send(const ValueType &); void receive(ValueType &); bool try_receive(ValueType &); void operator<<(const ValueType & to_send) { send(to_send); } receiving operator>>(ValueType & to_receive); { return receiving(this, to_receive); } ... };
  • 133. class receiving { public: receiving(channel * that, ValueType & to_receive) : that(that), to_receive(to_receive) { } receiving(receiving && other) : that(other.that), to_receive(other.to_receive) { other.that = nullptr; } operator bool() { auto from = that; that = nullptr; return from && from->try_receive(to_receive); } ~receiving() { if (that) that->receive(to_receive); } private: channel * that; ValueType & to_receive; };
  • 134. std::string fizzbuzz(int n) { if (n < 1 || n > 100) throw std::domain_error( "fizzbuzz(n) is defined for n in [1..100]") return n % 15 == 0 ? "FizzBuzz" : n % 3 == 0 ? "Fizz" : n % 5 == 0 ? "Buzz" : std::to_string(n); }
  • 135. void fizzbuzzer(channel<int> & in, channel<std::any> & out) { for (;;) { try { int n; in >> n; out << fizzbuzz(n); } catch (...) { out << std::current_exception(); } } }
  • 136. int main() { channel<int> out; channel<std::any> back; std::thread fizzbuzzing(fizzbuzzer, out, back) for (int n = 1; n <= 100; ++n) { out << n; std::any result; back >> result; if (result.type() == typeid(std::string)) std::cout << std::any_cast<std::string>(result) << "n"; } ... }
  • 137. template<typename ValueType> class channel { public: channel(); channel(std::function<void(const ValueType &)>); void send(const ValueType &); void receive(ValueType &); bool try_receive(ValueType &); void operator<<(const ValueType &); receiving operator>>(ValueType &); private: std::mutex key; std::condition_variable_any non_empty; std::deque<ValueType> fifo; };
  • 138. int main() { channel<int> out; channel<std::any> back( [](const any & received) { if (received.type() == typeid(std::exception_ptr)) std::rethrow_exception(any_cast<std::exception_ptr>(received)); }); std::thread fizzbuzzing(fizzbuzzer, out, back) ... }
  • 139. int main() { ... for (int n = 1; n <= 100; ++n) { try { out << n; std::any result; back >> result; std::cout << std::any_cast<std::string>(result) << "n"; } catch (std::domain_error & caught) { std::cout << caught.what() << "n"; } } ... }
  • 140. Pipes and Filters Divide the application's task into several self-contained data processing steps and connect these steps to a data processing pipeline via intermediate data buffers.
  • 141. Simple filters that can be arbitrarily chained are more easily re-used, and more robust, than almost any other kind of code. Brandon Rhodes http://rhodesmill.org/brandon/slides/2012-11-pyconca/
  • 142.
  • 143. Multithreading is just one damn thing after, before, or simultaneous with another. Andrei Alexandrescu
  • 144. Actor-based concurrency is just one damn message after another.
  • 145. No matter what language you work in, programming in a functional style provides benefits. You should do it whenever it is convenient, and you should think hard about the decision when it isn't convenient. John Carmack http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
  • 146. Programming in a functional style makes the state presented to your code explicit, which makes it much easier to reason about, and, in a completely pure system, makes thread race conditions impossible. John Carmack http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
  • 148. All computers wait at the same speed.