processing
Advanced tools
+1
-1
@@ -39,3 +39,3 @@ # | ||
| __version__ = '0.36' | ||
| __version__ = '0.37' | ||
@@ -42,0 +42,0 @@ __all__ = [ |
+4
-1
@@ -39,6 +39,9 @@ # | ||
| def prepare(main_path, sys_path, curdir, new_console): | ||
| def prepare(name, main_path, sys_path, curdir, new_console): | ||
| ''' | ||
| Try to get parents __main__ module and record it as sys.module['__main__'] | ||
| ''' | ||
| import processing | ||
| processing.currentProcess().setName(name) | ||
| if curdir is not None: | ||
@@ -45,0 +48,0 @@ try: |
+19
-0
@@ -5,3 +5,22 @@ ======================================== | ||
| Changes in 0.37 | ||
| --------------- | ||
| * Updated metadata and documentation because the project is now hosted | ||
| at `developer.berlios.de/projects/pyprocessing`. | ||
| * The `Pool.join()` method has been removed. `Pool.shutdown()` will | ||
| now join the worker processes automatically. | ||
| * A pool object no longer participates in a reference cycle so | ||
| `Pool.shutdown()` should get called as soon as its reference count | ||
| falls to zero. | ||
| * On Windows if `enableLogging()` was used at module scope then the | ||
| logger used by a child process would often get two copies of the | ||
| same handler. To fix this, now specifiying a handler type in | ||
| `enableLogging()` will cause any previous handlers used by the | ||
| logger to be discarded. | ||
| Changes in 0.36 | ||
@@ -8,0 +27,0 @@ --------------- |
+10
-21
@@ -7,3 +7,3 @@ <?xml version="1.0" encoding="utf-8" ?> | ||
| <meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" /> | ||
| <title>The processing package</title> | ||
| <title>Documentation for processing</title> | ||
| <meta name="author" content="R Oudkerk" /> | ||
@@ -14,7 +14,7 @@ <link rel="stylesheet" href="html4css1.css" type="text/css" /> | ||
| <div class="header"> | ||
| <a class="reference" href="index.html">Prev</a> <a class="reference" href="index.html">Up</a> <a class="reference" href="intro.html">Next</a> | ||
| <a class="reference" href="index.html">Prev</a> <a class="reference" href="../index.html">Up</a> <a class="reference" href="intro.html">Next</a> | ||
| <hr class="header"/> | ||
| </div> | ||
| <div class="document" id="the-processing-package"> | ||
| <h1 class="title">The processing package</h1> | ||
| <div class="document" id="documentation-for-processing"> | ||
| <h1 class="title">Documentation for processing</h1> | ||
| <table class="docinfo" frame="void" rules="none"> | ||
@@ -27,20 +27,10 @@ <col class="docinfo-name" /> | ||
| <tr><th class="docinfo-name">Contact:</th> | ||
| <td>r.m.oudkerk at gmail.com</td></tr> | ||
| <tr class="field"><th class="docinfo-name">Url:</th><td class="field-body"><a class="reference" href="http://cheeseshop.python.org/pypi/processing">http://cheeseshop.python.org/pypi/processing</a></td> | ||
| <td>roudkerk at users.berlios.de</td></tr> | ||
| <tr class="field"><th class="docinfo-name">Url:</th><td class="field-body"><a class="reference" href="http://developer.berlios.de/projects/pyprocessing">http://developer.berlios.de/projects/pyprocessing</a></td> | ||
| </tr> | ||
| <tr class="field"><th class="docinfo-name">Licence:</th><td class="field-body">BSD Licence</td> | ||
| </tr> | ||
| </tbody> | ||
| </table> | ||
| <div class="section"> | ||
| <h1><a id="description" name="description">Description</a></h1> | ||
| <p>The <tt class="docutils literal"><span class="pre">processing</span></tt> package is intended to be an analogue of the | ||
| <tt class="docutils literal"><span class="pre">threading</span></tt> module, but using processes instead of threads. It runs | ||
| on both Windows and Unix. A sub-package <tt class="docutils literal"><span class="pre">processing.dummy</span></tt> has the | ||
| same API, but is a thin wrapper around <tt class="docutils literal"><span class="pre">threading</span></tt>.</p> | ||
| <p>Communication between processes is mainly acheive by passing messages | ||
| over pipes or queues. Equivalents of all the synchronization | ||
| primitives in <tt class="docutils literal"><span class="pre">threading</span></tt> are provided.</p> | ||
| <p>Data can be shared between processes either by using shared memory or | ||
| by using proxies to objects in a server process.</p> | ||
| </div> | ||
| <div class="section"> | ||
| <h1><a id="contents" name="contents">Contents</a></h1> | ||
@@ -71,6 +61,5 @@ <ul> | ||
| <ul class="simple"> | ||
| <li><a class="reference" href="../README.txt">Readme</a></li> | ||
| <li><a class="reference" href="../index.html">Readme</a></li> | ||
| <li><a class="reference" href="../INSTALL.txt">Installation instructions</a></li> | ||
| <li><a class="reference" href="../CHANGES.txt">Changelog</a></li> | ||
| <li><a class="reference" href="../TODO.txt">To do</a></li> | ||
| <li><a class="reference" href="../THANKS.txt">Acknowledgments</a></li> | ||
@@ -83,5 +72,5 @@ <li><a class="reference" href="../COPYING.txt">Licence</a></li> | ||
| <hr class="footer" /> | ||
| <a class="reference" href="index.html">Prev</a> <a class="reference" href="index.html">Up</a> <a class="reference" href="intro.html">Next</a> | ||
| <a class="reference" href="index.html">Prev</a> <a class="reference" href="../index.html">Up</a> <a class="reference" href="intro.html">Next</a> | ||
| </div> | ||
| </body> | ||
| </html> |
+9
-24
| .. include:: header.txt | ||
| ======================== | ||
| The processing package | ||
| ======================== | ||
| ============================== | ||
| Documentation for processing | ||
| ============================== | ||
| :Author: R Oudkerk | ||
| :Contact: r.m.oudkerk at gmail.com | ||
| :Url: http://cheeseshop.python.org/pypi/processing | ||
| :Contact: roudkerk at users.berlios.de | ||
| :Url: http://developer.berlios.de/projects/pyprocessing | ||
| :Licence: BSD Licence | ||
| Description | ||
| =========== | ||
| The `processing` package is intended to be an analogue of the | ||
| `threading` module, but using processes instead of threads. It runs | ||
| on both Windows and Unix. A sub-package `processing.dummy` has the | ||
| same API, but is a thin wrapper around `threading`. | ||
| Communication between processes is mainly acheive by passing messages | ||
| over pipes or queues. Equivalents of all the synchronization | ||
| primitives in `threading` are provided. | ||
| Data can be shared between processes either by using shared memory or | ||
| by using proxies to objects in a server process. | ||
| Contents | ||
@@ -43,9 +28,9 @@ ======== | ||
| See also | ||
| ======== | ||
| * `Readme <../README.txt>`_ | ||
| * `Readme <../index.html>`_ | ||
| * `Installation instructions <../INSTALL.txt>`_ | ||
| * `Changelog <../CHANGES.txt>`_ | ||
| * `To do <../TODO.txt>`_ | ||
| * `Acknowledgments <../THANKS.txt>`_ | ||
@@ -55,3 +40,3 @@ * `Licence <../COPYING.txt>`_ | ||
| .. _Next: intro.html | ||
| .. _Up: index.html | ||
| .. _Up: ../index.html | ||
| .. _Prev: index.html |
+3
-5
@@ -97,5 +97,4 @@ <?xml version="1.0" encoding="utf-8" ?> | ||
| processes:</p> | ||
| <blockquote> | ||
| <dl class="docutils"> | ||
| <dt><em>Queues</em></dt> | ||
| <dt><strong>Queues</strong></dt> | ||
| <dd><p class="first">The function <tt class="docutils literal"><span class="pre">Queue()</span></tt> returns a near clone of <tt class="docutils literal"><span class="pre">Queue.Queue</span></tt> | ||
@@ -123,3 +122,3 @@ -- see the Python standard documentation. For example</p> | ||
| </dd> | ||
| <dt><em>Pipes</em></dt> | ||
| <dt><strong>Pipes</strong></dt> | ||
| <dd><p class="first">The <tt class="docutils literal"><span class="pre">Pipe()</span></tt> function returns a pair of connection objects | ||
@@ -131,3 +130,3 @@ connected by a duplex (two-way) pipe, for example</p> | ||
| def f(conn): | ||
| conn.send([42, None, 'hello']) | ||
| conn.send([42, None, 'hello']) | ||
@@ -150,3 +149,2 @@ if __name__ == '__main__': | ||
| </dl> | ||
| </blockquote> | ||
| </div> | ||
@@ -153,0 +151,0 @@ <div class="section"> |
+38
-38
@@ -103,50 +103,50 @@ .. include:: header.txt | ||
| *Queues* | ||
| The function `Queue()` returns a near clone of `Queue.Queue` | ||
| -- see the Python standard documentation. For example :: | ||
| **Queues**: | ||
| The function `Queue()` returns a near clone of `Queue.Queue` | ||
| -- see the Python standard documentation. For example :: | ||
| from processing import Process, Queue | ||
| from processing import Process, Queue | ||
| def f(q): | ||
| q.put([42, None, 'hello']) | ||
| def f(q): | ||
| q.put([42, None, 'hello']) | ||
| if __name__ == '__main__': | ||
| q = Queue() | ||
| p = Process(target=f, args=[q]) | ||
| p.start() | ||
| print q.get() # prints "[42, None, 'hello']" | ||
| p.join() | ||
| if __name__ == '__main__': | ||
| q = Queue() | ||
| p = Process(target=f, args=[q]) | ||
| p.start() | ||
| print q.get() # prints "[42, None, 'hello']" | ||
| p.join() | ||
| Queues are thread and process safe. | ||
| Queues are thread and process safe. | ||
| Note that if you need to guarantee that the `put()` method | ||
| will succeed without blocking -- which is sometimes very | ||
| useful when ensuring that a deadlock cannot occur -- then you | ||
| can use `BufferedQueue()` instead of `Queue()`. | ||
| See `Queues <processing-ref.html#pipes-and-queues>`_. | ||
| Note that if you need to guarantee that the `put()` method | ||
| will succeed without blocking -- which is sometimes very | ||
| useful when ensuring that a deadlock cannot occur -- then you | ||
| can use `BufferedQueue()` instead of `Queue()`. | ||
| See `Queues <processing-ref.html#pipes-and-queues>`_. | ||
| *Pipes* | ||
| The `Pipe()` function returns a pair of connection objects | ||
| connected by a duplex (two-way) pipe, for example :: | ||
| **Pipes**: | ||
| The `Pipe()` function returns a pair of connection objects | ||
| connected by a duplex (two-way) pipe, for example :: | ||
| from processing import Process, Pipe | ||
| from processing import Process, Pipe | ||
| def f(conn): | ||
| conn.send([42, None, 'hello']) | ||
| def f(conn): | ||
| conn.send([42, None, 'hello']) | ||
| if __name__ == '__main__': | ||
| parent_conn, child_conn = Pipe() | ||
| p = Process(target=f, args=[child_conn]) | ||
| p.start() | ||
| print parent_conn.recv() # prints "[42, None, 'hello']" | ||
| p.join() | ||
| if __name__ == '__main__': | ||
| parent_conn, child_conn = Pipe() | ||
| p = Process(target=f, args=[child_conn]) | ||
| p.start() | ||
| print parent_conn.recv() # prints "[42, None, 'hello']" | ||
| p.join() | ||
| The two connection objects returned by `Pipe()` represent the | ||
| two ends of the pipe. Each connection object has `send()` and | ||
| `recv()` methods (among others). Note that data in a pipe may | ||
| become corrupted if two processes (or threads) try to | ||
| read/write to the *same* end of the pipe at the same time. Of | ||
| course there is no risk of corruption from processes using | ||
| different ends of the pipe at the same time. See `Pipes | ||
| <processing-ref.html#pipes-and-queues>`_. | ||
| The two connection objects returned by `Pipe()` represent the | ||
| two ends of the pipe. Each connection object has `send()` and | ||
| `recv()` methods (among others). Note that data in a pipe may | ||
| become corrupted if two processes (or threads) try to | ||
| read/write to the *same* end of the pipe at the same time. Of | ||
| course there is no risk of corruption from processes using | ||
| different ends of the pipe at the same time. See `Pipes | ||
| <processing-ref.html#pipes-and-queues>`_. | ||
@@ -153,0 +153,0 @@ |
@@ -82,5 +82,2 @@ <?xml version="1.0" encoding="utf-8" ?> | ||
| when the process shuts down.</dd> | ||
| <dt><tt class="docutils literal"><span class="pre">join()</span></tt></dt> | ||
| <dd>Tells the worker processes to shutdown and waits for them to | ||
| finish.</dd> | ||
| </dl> | ||
@@ -87,0 +84,0 @@ </blockquote> |
@@ -80,7 +80,3 @@ .. include:: header.txt | ||
| `join()` | ||
| Tells the worker processes to shutdown and waits for them to | ||
| finish. | ||
| Asynchronous result objects | ||
@@ -87,0 +83,0 @@ =========================== |
@@ -277,7 +277,9 @@ <?xml version="1.0" encoding="utf-8" ?> | ||
| <p>If <tt class="docutils literal"><span class="pre">HandlerType</span></tt> is specified then a handler is created using | ||
| <tt class="docutils literal"><span class="pre">HandlerType(*handlerArgs)</span></tt> and added to the logger. If | ||
| <tt class="docutils literal"><span class="pre">format</span></tt> is specified then this will be used for the handler | ||
| -- <tt class="docutils literal"><span class="pre">format</span></tt> defaults to <tt class="docutils literal"><span class="pre">'[%(levelname)s/%(processName)s]</span> | ||
| <span class="pre">%(message)s'</span></tt>. (The logger used by <tt class="docutils literal"><span class="pre">processing</span></tt> allows use of | ||
| the non-standard <tt class="docutils literal"><span class="pre">'%(processName)s'</span></tt> format.)</p> | ||
| <tt class="docutils literal"><span class="pre">HandlerType(*handlerArgs)</span></tt> and this will be used by the | ||
| logger -- any previous handlers will be discarded. If | ||
| <tt class="docutils literal"><span class="pre">format</span></tt> is specified then this will be used for the handler; | ||
| otherwise <tt class="docutils literal"><span class="pre">format</span></tt> defaults to | ||
| <tt class="docutils literal"><span class="pre">'[%(levelname)s/%(processName)s]</span> <span class="pre">%(message)s'</span></tt>. (The logger | ||
| used by <tt class="docutils literal"><span class="pre">processing</span></tt> allows use of the non-standard | ||
| <tt class="docutils literal"><span class="pre">'%(processName)s'</span></tt> format.)</p> | ||
| <p>If <tt class="docutils literal"><span class="pre">HandlerType</span></tt> is not specified and the logger has no | ||
@@ -284,0 +286,0 @@ handlers then a default one is created which prints to |
@@ -287,12 +287,14 @@ .. include:: header.txt | ||
| `enableLogging(level, HandlerType=None, handlerArgs=(), format=None)` | ||
| Enables logging and sets the debug level to `level` -- see | ||
| documentation for the `logging` package in the standard | ||
| library. | ||
| Enables logging and sets the debug level used by the package's | ||
| logger to `level` -- see documentation for the `logging` | ||
| package in the standard library. | ||
| If `HandlerType` is specified then a handler is created using | ||
| `HandlerType(*handlerArgs)` and added to the logger. If | ||
| `format` is specified then this will be used for the handler | ||
| -- `format` defaults to `'[%(levelname)s/%(processName)s] | ||
| %(message)s'`. (The logger used by `processing` allows use of | ||
| the non-standard `'%(processName)s'` format.) | ||
| `HandlerType(*handlerArgs)` and this will be used by the | ||
| logger -- any previous handlers will be discarded. If | ||
| `format` is specified then this will be used for the handler; | ||
| otherwise `format` defaults to | ||
| `'[%(levelname)s/%(processName)s] %(message)s'`. (The logger | ||
| used by `processing` allows use of the non-standard | ||
| `'%(processName)s'` format.) | ||
@@ -299,0 +301,0 @@ If `HandlerType` is not specified and the logger has no |
+91
-8
@@ -1,13 +0,96 @@ | ||
| <html> | ||
| <?xml version="1.0" encoding="utf-8" ?> | ||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | ||
| <head> | ||
| <title>Redirect Page</title> | ||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | ||
| <meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" /> | ||
| <title>Python processing</title> | ||
| <meta name="author" content="R Oudkerk" /> | ||
| <link rel="stylesheet" href="doc/html4css1.css" type="text/css" /> | ||
| </head> | ||
| <body> | ||
| <script type="text/javascript"> | ||
| <!-- | ||
| window.location.replace("doc/index.html"); | ||
| // --> | ||
| </script> | ||
| If you don't get redirected <a href="doc/index.html">click here</a>. | ||
| <div class="document" id="python-processing"> | ||
| <h1 class="title">Python processing</h1> | ||
| <table class="docinfo" frame="void" rules="none"> | ||
| <col class="docinfo-name" /> | ||
| <col class="docinfo-content" /> | ||
| <tbody valign="top"> | ||
| <tr><th class="docinfo-name">Author:</th> | ||
| <td>R Oudkerk</td></tr> | ||
| <tr><th class="docinfo-name">Contact:</th> | ||
| <td>roudkerk at users.berlios.de</td></tr> | ||
| <tr class="field"><th class="docinfo-name">Url:</th><td class="field-body"><a class="reference" href="http://developer.berlios.de/projects/pyprocessing">http://developer.berlios.de/projects/pyprocessing</a></td> | ||
| </tr> | ||
| <tr class="field"><th class="docinfo-name">Licence:</th><td class="field-body">BSD Licence</td> | ||
| </tr> | ||
| </tbody> | ||
| </table> | ||
| <p><tt class="docutils literal"><span class="pre">processing</span></tt> is a package for the Python language which supports the | ||
| spawning of processes using the API of the standard library's | ||
| <tt class="docutils literal"><span class="pre">threading</span></tt> module. It runs on both Unix and Windows.</p> | ||
| <p>Objects can be transferred between processes using pipes or queues, | ||
| and objects can be shared between processes using a server process or | ||
| (for simple data) shared memory. Equivalents of the synchronization | ||
| primitives in <tt class="docutils literal"><span class="pre">threading</span></tt> are also provided.</p> | ||
| <div class="section"> | ||
| <h1><a id="links" name="links">Links</a></h1> | ||
| <ul class="simple"> | ||
| <li><a class="reference" href="./doc/index.html">Documentation</a></li> | ||
| <li><a class="reference" href="./INSTALL.txt">Installation instructions</a></li> | ||
| <li><a class="reference" href="./CHANGES.txt">Changelog</a></li> | ||
| <li><a class="reference" href="./THANKS.txt">Acknowledgments</a></li> | ||
| <li><a class="reference" href="./COPYING.txt">BSD Licence</a></li> | ||
| </ul> | ||
| <p>The package can be downloaded from</p> | ||
| <ul class="simple"> | ||
| <li><a class="reference" href="http://developer.berlios.de/project/filelist.php?group_id=9001">http://developer.berlios.de/project/filelist.php?group_id=9001</a> or</li> | ||
| <li><a class="reference" href="http://cheeseshop.python.org/pypi/processing">http://cheeseshop.python.org/pypi/processing</a></li> | ||
| </ul> | ||
| </div> | ||
| <div class="section"> | ||
| <h1><a id="examples" name="examples">Examples</a></h1> | ||
| <p>The <tt class="docutils literal"><span class="pre">processing.Process</span></tt> class follows the API of <tt class="docutils literal"><span class="pre">threading.Thread</span></tt>. | ||
| For example</p> | ||
| <pre class="literal-block"> | ||
| from processing import Process, Queue | ||
| def f(q): | ||
| q.put('hello world') | ||
| if __name__ == '__main__': | ||
| q = Queue() | ||
| p = Process(target=f, args=[q]) | ||
| p.start() | ||
| print q.get() | ||
| p.join() | ||
| </pre> | ||
| <p>Synchronization primitives like locks, semaphores and conditions are | ||
| available, for example</p> | ||
| <pre class="literal-block"> | ||
| >>> from processing import Condition | ||
| >>> c = Condition() | ||
| >>> print c | ||
| <Condition(<RLock(None, 0)>), 0> | ||
| >>> c.acquire() | ||
| True | ||
| >>> print c | ||
| <Condition(<RLock(MainProcess, 1)>), 0> | ||
| </pre> | ||
| <p>One can also use a manager to create shared objects either in shared | ||
| memory or in a server process, for example</p> | ||
| <pre class="literal-block"> | ||
| >>> from processing import Manager | ||
| >>> manager = Manager() | ||
| >>> l = manager.list(range(10)) | ||
| >>> l.reverse() | ||
| >>> print l | ||
| [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] | ||
| >>> print repr(l) | ||
| <Proxy[list] object at 0x00E1B3B0> | ||
| </pre> | ||
| <a href="http://developer.berlios.de" title="BerliOS Developer"> | ||
| <img src="http://developer.berlios.de/bslogo.php?group_id=9001" | ||
| width="124px" height="32px" border="0" alt="BerliOS Developer Logo"></a></div> | ||
| </div> | ||
| </body> | ||
| </html> |
+2
-2
@@ -8,3 +8,3 @@ ========================================== | ||
| http://cheeseshop.python.org/pypi/processing | ||
| http://pyprocessing.berlios.de | ||
@@ -19,3 +19,3 @@ Otherwise, if you have the correct C compiler setup then the source | ||
| necessary to modify the values of the `macros` dictionary or | ||
| `libraries` variables. The section to modify reads :: | ||
| `libraries` list. The section to modify reads :: | ||
@@ -22,0 +22,0 @@ macros = dict( |
+1
-1
@@ -861,3 +861,3 @@ # | ||
| ''' | ||
| log(5, 'reset all proxies -- process name is really [%r]', process_name) | ||
| log(5, 'reset all proxies') | ||
| _Private._mutex.acquire() | ||
@@ -864,0 +864,0 @@ try: |
+31
-17
| Metadata-Version: 1.0 | ||
| Name: processing | ||
| Version: 0.36 | ||
| Version: 0.37 | ||
| Summary: Package for using processes mimicking the `threading` module | ||
| Home-page: http://cheeseshop.python.org/pypi/processing | ||
| Home-page: http://developer.berlios.de/projects/pyprocessing | ||
| Author: R Oudkerk | ||
| Author-email: r.m.oudkerk at gmail.com | ||
| Author-email: roudkerk at users.berlios.de | ||
| License: BSD Licence | ||
| Description: | ||
| Package for using processes which mimics the threading module, and | ||
| allows the sharing of objects between processes. | ||
| ``processing`` is a package for the Python language which supports the | ||
| spawning of processes using the API of the standard library's | ||
| ``threading`` module. It runs on both Unix and Windows. | ||
| Objects can be transferred between processes using pipes or queues, | ||
| and objects can be shared between processes using a server process or | ||
| (for simple data) shared memory. Equivalents of the synchronization | ||
| primitives in ``threading`` are also provided. | ||
| Links | ||
| ===== | ||
| * `Documentation <http://pyprocessing.berlios.de/doc/index.html>`_ | ||
| * `Installation instructions <http://pyprocessing.berlios.de/INSTALL.txt>`_ | ||
| * `Changelog <http://pyprocessing.berlios.de/CHANGES.txt>`_ | ||
| * `Acknowledgments <http://pyprocessing.berlios.de/THANKS.txt>`_ | ||
| * `BSD Licence <http://pyprocessing.berlios.de/COPYING.txt>`_ | ||
| The package can be downloaded from | ||
| * http://developer.berlios.de/project/filelist.php?group_id=9001 or | ||
| * http://cheeseshop.python.org/pypi/processing | ||
| Examples | ||
| ======== | ||
| The ``processing.Process`` class follows the API of ``threading.Thread``. | ||
@@ -52,16 +78,4 @@ For example :: | ||
| After installation you can run the test scripts by doing either :: | ||
| python -m processing.test | ||
| on Python 2.5 or :: | ||
| python -c "from processing.test import main; main()" | ||
| on Python 2.4. This will run various test scripts using both | ||
| processes and threads. | ||
| See ``README.txt`` and ``doc/index.html`` in the package directory for | ||
| more information. | ||
| Platform: Unix and Windows | ||
@@ -68,0 +82,0 @@ Classifier: Development Status :: 4 - Beta |
+33
-21
@@ -71,4 +71,4 @@ # | ||
| for w in self._pool: | ||
| w.setDaemon(True) | ||
| for i, w in enumerate(self._pool): | ||
| w.setName('PoolWorker-' + ':'.join(map(str, w._identity))) | ||
| w.start() | ||
@@ -81,7 +81,9 @@ | ||
| thandler = threading.Thread(target=self._handle_tasks) | ||
| thandler = threading.Thread(target=Pool._handle_tasks, | ||
| args=[self._taskqueue, self._inqueue]) | ||
| thandler.setDaemon(True) | ||
| thandler.start() | ||
| rhandler = threading.Thread(target=self._handle_results) | ||
| rhandler = threading.Thread(target=Pool._handle_results, | ||
| args=[self._outqueue, self._cache]) | ||
| rhandler.setDaemon(True) | ||
@@ -92,3 +94,4 @@ rhandler.start() | ||
| self, Pool._finalize_pool, | ||
| args=(self._taskqueue, self._outqueue, thandler, rhandler), | ||
| args=(self._taskqueue, self._inqueue, self._outqueue, | ||
| thandler, rhandler, self._pool), | ||
| atexit=True | ||
@@ -157,5 +160,6 @@ ) | ||
| def _handle_tasks(self): | ||
| put = self._inqueue._put | ||
| for taskseq, setlength in iter(self._taskqueue.get, None): | ||
| # staticmethod | ||
| def _handle_tasks(taskqueue, inqueue): | ||
| put = inqueue._put | ||
| for taskseq, setlength in iter(taskqueue.get, None): | ||
| i = -1 | ||
@@ -166,8 +170,7 @@ for i, task in enumerate(taskseq): | ||
| setlength(i+1) | ||
| for p in self._pool: | ||
| put(None) | ||
| _handle_tasks = staticmethod(_handle_tasks) | ||
| def _handle_results(self): | ||
| cache = self._cache | ||
| for job, i, obj in iter(self._outqueue._get, None): | ||
| # staticmethod | ||
| def _handle_results(outqueue, cache): | ||
| for job, i, obj in iter(outqueue._get, None): | ||
| try: | ||
@@ -177,19 +180,28 @@ cache[job]._set(i, obj) | ||
| pass | ||
| def join(self): | ||
| self.shutdown() | ||
| for p in self._pool: | ||
| p.join() | ||
| _handle_results = staticmethod(_handle_results) | ||
| # staticmethod | ||
| def _finalize_pool(taskqueue, outqueue, task_handler, result_handler): | ||
| def _finalize_pool(taskqueue, inqueue, outqueue, | ||
| task_handler, result_handler, pool): | ||
| # stop task handler thread | ||
| taskqueue.not_empty.acquire() | ||
| try: | ||
| taskqueue.queue.clear() | ||
| taskqueue.queue.append(None) | ||
| taskqueue.not_empty.notify() | ||
| finally: | ||
| taskqueue.not_empty.release() | ||
| taskqueue.put(None) | ||
| # stop result handler thread | ||
| outqueue.put(None) | ||
| # stop work processes | ||
| for p in pool: | ||
| inqueue.put(None) | ||
| # join all the threads and processes | ||
| task_handler.join() | ||
| result_handler.join() | ||
| for p in pool: | ||
| p.join() | ||
| _finalize_pool = staticmethod(_finalize_pool) | ||
@@ -196,0 +208,0 @@ |
+9
-6
@@ -274,6 +274,7 @@ # | ||
| Finalize._registry.clear() | ||
| _current_process._name = self._name | ||
| if sys.platform == 'win32' and self._logargs is not None: | ||
| enableLogging(*self._logargs) | ||
| _reset_all_proxies(self.getAuthKey(), self.getName()) | ||
| _current_process = self | ||
| if sys.platform == 'win32' and self._logargs is not None: | ||
| enableLogging(*self._logargs) | ||
| info('process starting up') | ||
@@ -363,6 +364,7 @@ try: | ||
| def _reset_all_proxies(authkey, process_name): | ||
| def _reset_all_proxies(authkey, name): | ||
| ''' | ||
| Dummy function that will be overwritten if `processing.managers` loads | ||
| ''' | ||
| log(5, 'dummy reset all proxies') | ||
@@ -429,3 +431,4 @@ # | ||
| _mainpath = None | ||
| preparation_data = [_mainpath, sys.path, os.getcwd(), new_console] | ||
| preparation_data = [process_obj._name, _mainpath, | ||
| sys.path, os.getcwd(), new_console] | ||
@@ -610,2 +613,3 @@ flags = new_console and _cflags | ||
| _logger.propagate = 0 | ||
| logging.addLevelName(5, 'SUBDEBUG') | ||
@@ -626,6 +630,5 @@ # we want `_logger` to support the "%(processName)s" format | ||
| format = format or '[%(levelname)s/%(processName)s] %(message)s' | ||
| handler = HandlerType(*handlerArgs) | ||
| handler.setFormatter(logging.Formatter(format)) | ||
| _logger.addHandler(handler) | ||
| _logger.handlers = [handler] | ||
| _logger.setLevel(level) | ||
@@ -632,0 +635,0 @@ _current_process._logargs = [level,HandlerType,handlerArgs,format] |
+77
-16
@@ -1,23 +0,84 @@ | ||
| =================================== | ||
| README for the processing package | ||
| =================================== | ||
| =================== | ||
| Python processing | ||
| =================== | ||
| :Author: R Oudkerk | ||
| :Contact: r.m.oudkerk at gmail.com | ||
| :Url: http://cheeseshop.python.org/pypi/processing | ||
| :Author: R Oudkerk | ||
| :Contact: roudkerk at users.berlios.de | ||
| :Url: http://developer.berlios.de/projects/pyprocessing | ||
| :Licence: BSD Licence | ||
| The processing package is and analogue of the `threading` module, but | ||
| using processes instead of threads. A sub-package `processing.dummy` has | ||
| the same API, but is a thin wrapper around `threading`. | ||
| For passing data between processes one can use pipes or queues. | ||
| Synchronization primitives like locks, semaphores conditions are also | ||
| available. The sharing of objects between processes is possible by | ||
| using a "manager". | ||
| ``processing`` is a package for the Python language which supports the | ||
| spawning of processes using the API of the standard library's | ||
| ``threading`` module. It runs on both Unix and Windows. | ||
| See `<INSTALL.txt>`_ for installation instructions. | ||
| Objects can be transferred between processes using pipes or queues, | ||
| and objects can be shared between processes using a server process or | ||
| (for simple data) shared memory. Equivalents of the synchronization | ||
| primitives in ``threading`` are also provided. | ||
| The package is released under the BSD Licence, see `<LICENCE.txt>`_. | ||
| For further documentation see `<doc/index.html>`_. | ||
| Links | ||
| ===== | ||
| * `Documentation <./doc/index.html>`_ | ||
| * `Installation instructions <./INSTALL.txt>`_ | ||
| * `Changelog <./CHANGES.txt>`_ | ||
| * `Acknowledgments <./THANKS.txt>`_ | ||
| * `BSD Licence <./COPYING.txt>`_ | ||
| The package can be downloaded from | ||
| * http://developer.berlios.de/project/filelist.php?group_id=9001 or | ||
| * http://cheeseshop.python.org/pypi/processing | ||
| Examples | ||
| ======== | ||
| The ``processing.Process`` class follows the API of ``threading.Thread``. | ||
| For example :: | ||
| from processing import Process, Queue | ||
| def f(q): | ||
| q.put('hello world') | ||
| if __name__ == '__main__': | ||
| q = Queue() | ||
| p = Process(target=f, args=[q]) | ||
| p.start() | ||
| print q.get() | ||
| p.join() | ||
| Synchronization primitives like locks, semaphores and conditions are | ||
| available, for example :: | ||
| >>> from processing import Condition | ||
| >>> c = Condition() | ||
| >>> print c | ||
| <Condition(<RLock(None, 0)>), 0> | ||
| >>> c.acquire() | ||
| True | ||
| >>> print c | ||
| <Condition(<RLock(MainProcess, 1)>), 0> | ||
| One can also use a manager to create shared objects either in shared | ||
| memory or in a server process, for example :: | ||
| >>> from processing import Manager | ||
| >>> manager = Manager() | ||
| >>> l = manager.list(range(10)) | ||
| >>> l.reverse() | ||
| >>> print l | ||
| [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] | ||
| >>> print repr(l) | ||
| <Proxy[list] object at 0x00E1B3B0> | ||
| .. raw:: html | ||
| <a href="http://developer.berlios.de" title="BerliOS Developer"> | ||
| <img src="http://developer.berlios.de/bslogo.php?group_id=9001" | ||
| width="124px" height="32px" border="0" alt="BerliOS Developer Logo"></a> |
+4
-0
@@ -47,2 +47,3 @@ # | ||
| def reduce_handle(handle): | ||
| process.log(5, 'reducing handle %d', handle) | ||
| return (os.getpid(), handle) | ||
@@ -52,2 +53,3 @@ | ||
| pid, old_handle = reduced_handle | ||
| process.log(5, 'rebuilding handle %d from PID=%d', old_handle, pid) | ||
| return _processing.HandleFromPidHandle(pid, old_handle) | ||
@@ -133,2 +135,3 @@ | ||
| _fd_cache.add(dup_fd) | ||
| process.log(5, 'reducing fd %d', fd) | ||
| return (_fd_listener.address, dup_fd) | ||
@@ -139,2 +142,3 @@ | ||
| address, fd = reduced_handle | ||
| process.log(5, 'rebuilding fd %d', fd) | ||
| conn = Client(address, authenticate=True) | ||
@@ -141,0 +145,0 @@ conn.send(fd) |
+16
-62
@@ -1,59 +0,1 @@ | ||
| ''' | ||
| Package for using processes which mimics the threading module, and | ||
| allows the sharing of objects between processes. | ||
| The ``processing.Process`` class follows the API of ``threading.Thread``. | ||
| For example :: | ||
| from processing import Process, Queue | ||
| def f(q): | ||
| q.put('hello world') | ||
| if __name__ == '__main__': | ||
| q = Queue() | ||
| p = Process(target=f, args=[q]) | ||
| p.start() | ||
| print q.get() | ||
| p.join() | ||
| Synchronization primitives like locks, semaphores and conditions are | ||
| available, for example :: | ||
| >>> from processing import Condition | ||
| >>> c = Condition() | ||
| >>> print c | ||
| <Condition(<RLock(None, 0)>), 0> | ||
| >>> c.acquire() | ||
| True | ||
| >>> print c | ||
| <Condition(<RLock(MainProcess, 1)>), 0> | ||
| One can also use a manager to create shared objects either in shared | ||
| memory or in a server process, for example :: | ||
| >>> from processing import Manager | ||
| >>> manager = Manager() | ||
| >>> l = manager.list(range(10)) | ||
| >>> l.reverse() | ||
| >>> print l | ||
| [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] | ||
| >>> print repr(l) | ||
| <Proxy[list] object at 0x00E1B3B0> | ||
| After installation you can run the test scripts by doing either :: | ||
| python -m processing.test | ||
| on Python 2.5 or :: | ||
| python -c "from processing.test import main; main()" | ||
| on Python 2.4. This will run various test scripts using both | ||
| processes and threads. | ||
| See ``README.txt`` and ``doc/index.html`` in the package directory for | ||
| more information. | ||
| ''' | ||
| # | ||
@@ -143,6 +85,5 @@ # Imports | ||
| 'the `threading` module'), | ||
| long_description=__doc__, | ||
| author='R Oudkerk', | ||
| author_email='r.m.oudkerk at gmail.com', | ||
| url='http://cheeseshop.python.org/pypi/processing', | ||
| author_email='roudkerk at users.berlios.de', | ||
| url='http://developer.berlios.de/projects/pyprocessing', | ||
| license='BSD Licence', | ||
@@ -157,3 +98,3 @@ platforms='Unix and Windows', | ||
| package_dir={'processing': '.'}, | ||
| packages=['processing', 'processing.dummy', 'processing'] | ||
| packages=['processing', 'processing.dummy'] | ||
| ) | ||
@@ -212,2 +153,15 @@ | ||
| # | ||
| # Get `long_description` from `README.txt` | ||
| # | ||
| doc = open('README.txt', 'rU').read() | ||
| start_string = ':Licence: BSD Licence\n\n' | ||
| end_string = '.. raw:: html' | ||
| start = doc.index(start_string) + len(start_string) | ||
| end = doc.index(end_string) | ||
| doc = doc[start:end] | ||
| doc = doc.replace('<./', '<http://pyprocessing.berlios.de/') | ||
| kwds['long_description'] = doc | ||
| # | ||
| # Setup | ||
@@ -214,0 +168,0 @@ # |
+5
-1
@@ -5,3 +5,3 @@ # | ||
| from processing import Process, freezeSupport, HAVE_NATIVE_SEMAPHORE | ||
| from processing import activeChildren, freezeSupport, HAVE_NATIVE_SEMAPHORE | ||
@@ -32,2 +32,4 @@ | ||
| old_processes = set(activeChildren()) | ||
| run_test(test_doc, ['processes+server', 'threads']) | ||
@@ -47,2 +49,4 @@ run_test(test_connection, ['processes', 'threads']) | ||
| processes = set(activeChildren()) | ||
| assert processes.issubset(old_processes) | ||
@@ -49,0 +53,0 @@ if __name__ == '__main__': |
@@ -41,3 +41,3 @@ # | ||
| def runpool(address, number_of_processes): | ||
| def runpool(address, number_of_processes): | ||
| # create a single server object -- children will each inherit a copy | ||
@@ -44,0 +44,0 @@ server = HTTPServer(address, RequestHandler) |
+15
-1
@@ -6,3 +6,3 @@ # | ||
| from processing import Pool, TimeoutError | ||
| from processing import cpuCount, currentProcess, freezeSupport | ||
| from processing import cpuCount, currentProcess, freezeSupport, activeChildren | ||
@@ -220,5 +220,19 @@ import time, random, sys | ||
| # | ||
| # Check that processes get stopped when pool is deleted | ||
| # | ||
| processes = pool._pool | ||
| for worker in processes: | ||
| assert worker.isAlive() | ||
| del pool | ||
| for worker in processes: | ||
| assert not worker.isAlive() | ||
| if __name__ == '__main__': | ||
| freezeSupport() | ||
| test() |
-5
| ======= | ||
| To do | ||
| ======= | ||
| * Nothing for now -- just let API stabilize and fix bugs |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
517699
1.06%64
-1.54%5580
-0.02%