{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Copyright 2014 Brett Slatkin, Pearson Education Inc.\n", "#\n", "# Licensed under the Apache License, Version 2.0 (the \"License\");\n", "# you may not use this file except in compliance with the License.\n", "# You may obtain a copy of the License at\n", "#\n", "# http://www.apache.org/licenses/LICENSE-2.0\n", "#\n", "# Unless required by applicable law or agreed to in writing, software\n", "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", "# See the License for the specific language governing permissions and\n", "# limitations under the License.\n", "\n", "# Preamble to mimick book environment\n", "import logging\n", "from pprint import pprint\n", "from sys import stdout as STDOUT" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Example 1\n", "class Counter(object):\n", " def __init__(self):\n", " self.count = 0\n", "\n", " def increment(self, offset):\n", " self.count += offset" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Example 2\n", "def worker(sensor_index, how_many, counter):\n", " # I have a barrier in here so the workers synchronize\n", " # when they start counting, otherwise it's hard to get a race\n", " # because the overhead of starting a thread is high.\n", " BARRIER.wait()\n", " for _ in range(how_many):\n", " # Read from the sensor\n", " counter.increment(1)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Example 3\n", "from threading import Barrier, Thread\n", "BARRIER = Barrier(5)\n", "def run_threads(func, how_many, counter):\n", " threads = []\n", " for i in range(5):\n", " args = (i, how_many, counter)\n", " thread = Thread(target=func, args=args)\n", " threads.append(thread)\n", " thread.start()\n", " for thread in threads:\n", " thread.join()" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Counter should be 500000, found 202643\n" ] } ], "source": [ "# Example 4\n", "how_many = 10**5\n", "counter = Counter()\n", "run_threads(worker, how_many, counter)\n", "print('Counter should be %d, found %d' %\n", " (5 * how_many, counter.count))" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Example 5\n", "offset = 5\n", "counter.count += offset" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Example 6\n", "value = getattr(counter, 'count')\n", "result = value + offset\n", "setattr(counter, 'count', result)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Example 7\n", "# Running in Thread A\n", "value_a = getattr(counter, 'count')\n", "# Context switch to Thread B\n", "value_b = getattr(counter, 'count')\n", "result_b = value_b + 1\n", "setattr(counter, 'count', result_b)\n", "# Context switch back to Thread A\n", "result_a = value_a + 1\n", "setattr(counter, 'count', result_a)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Example 8\n", "from threading import Lock\n", "\n", "class LockingCounter(object):\n", " def __init__(self):\n", " self.lock = Lock()\n", " self.count = 0\n", "\n", " def increment(self, offset):\n", " with self.lock:\n", " self.count += offset" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Counter should be 500000, found 500000\n" ] } ], "source": [ "# Example 9\n", "BARRIER = Barrier(5)\n", "counter = LockingCounter()\n", "run_threads(worker, how_many, counter)\n", "print('Counter should be %d, found %d' %\n", " (5 * how_many, counter.count))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.1" } }, "nbformat": 4, "nbformat_minor": 0 }