Show More
@@ -0,0 +1,56 b'' | |||||
|
1 | { | |||
|
2 | "metadata": { | |||
|
3 | "name": "gilsleep" | |||
|
4 | }, | |||
|
5 | "nbformat": 2, | |||
|
6 | "worksheets": [ | |||
|
7 | { | |||
|
8 | "cells": [ | |||
|
9 | { | |||
|
10 | "cell_type": "markdown", | |||
|
11 | "source": [ | |||
|
12 | "Holding the GIL for too long could disrupt the heartbeat due to non-copying sends.", | |||
|
13 | "", | |||
|
14 | "The following cell repeatedly calls a function that holds the GIL for five seconds.", | |||
|
15 | "", | |||
|
16 | "The heartbeat will fail after a few iterations prior to fixing Issue [#1260](https://github.com/ipython/ipython/issues/1260)." | |||
|
17 | ] | |||
|
18 | }, | |||
|
19 | { | |||
|
20 | "cell_type": "code", | |||
|
21 | "collapsed": false, | |||
|
22 | "input": [ | |||
|
23 | "import sys", | |||
|
24 | "import time", | |||
|
25 | "", | |||
|
26 | "from cython import inline", | |||
|
27 | "", | |||
|
28 | "def gilsleep(t):", | |||
|
29 | " \"\"\"gil-holding sleep with cython.inline\"\"\"", | |||
|
30 | " code = '\\n'.join([", | |||
|
31 | " 'from posix cimport unistd',", | |||
|
32 | " 'unistd.sleep(t)',", | |||
|
33 | " ])", | |||
|
34 | " while True:", | |||
|
35 | " inline(code, quiet=True, t=t)", | |||
|
36 | " print time.time()", | |||
|
37 | " sys.stdout.flush() # this is important", | |||
|
38 | "", | |||
|
39 | "gilsleep(5)" | |||
|
40 | ], | |||
|
41 | "language": "python", | |||
|
42 | "outputs": [], | |||
|
43 | "prompt_number": 1 | |||
|
44 | }, | |||
|
45 | { | |||
|
46 | "cell_type": "code", | |||
|
47 | "collapsed": true, | |||
|
48 | "input": [], | |||
|
49 | "language": "python", | |||
|
50 | "outputs": [], | |||
|
51 | "prompt_number": " " | |||
|
52 | } | |||
|
53 | ] | |||
|
54 | } | |||
|
55 | ] | |||
|
56 | } No newline at end of file |
@@ -0,0 +1,31 b'' | |||||
|
1 | """ | |||
|
2 | Run this script in the qtconsole with one of: | |||
|
3 | ||||
|
4 | %loadpy hb_gil.py | |||
|
5 | ||||
|
6 | or | |||
|
7 | %run hb_gil.py | |||
|
8 | ||||
|
9 | Holding the GIL for too long could disrupt the heartbeat. | |||
|
10 | ||||
|
11 | See Issue #1260: https://github.com/ipython/ipython/issues/1260 | |||
|
12 | ||||
|
13 | """ | |||
|
14 | ||||
|
15 | import sys | |||
|
16 | import time | |||
|
17 | ||||
|
18 | from cython import inline | |||
|
19 | ||||
|
20 | def gilsleep(t): | |||
|
21 | """gil-holding sleep with cython.inline""" | |||
|
22 | code = '\n'.join([ | |||
|
23 | 'from posix cimport unistd', | |||
|
24 | 'unistd.sleep(t)', | |||
|
25 | ]) | |||
|
26 | while True: | |||
|
27 | inline(code, quiet=True, t=t) | |||
|
28 | print time.time() | |||
|
29 | sys.stdout.flush() # this is important | |||
|
30 | ||||
|
31 | gilsleep(5) |
@@ -40,6 +40,10 b' class Heart(object):' | |||||
40 | id=None |
|
40 | id=None | |
41 | def __init__(self, in_addr, out_addr, in_type=zmq.SUB, out_type=zmq.DEALER, heart_id=None): |
|
41 | def __init__(self, in_addr, out_addr, in_type=zmq.SUB, out_type=zmq.DEALER, heart_id=None): | |
42 | self.device = ThreadDevice(zmq.FORWARDER, in_type, out_type) |
|
42 | self.device = ThreadDevice(zmq.FORWARDER, in_type, out_type) | |
|
43 | # do not allow the device to share global Context.instance, | |||
|
44 | # which is the default behavior in pyzmq > 2.1.10 | |||
|
45 | self.device.context_factory = zmq.Context | |||
|
46 | ||||
43 | self.device.daemon=True |
|
47 | self.device.daemon=True | |
44 | self.device.connect_in(in_addr) |
|
48 | self.device.connect_in(in_addr) | |
45 | self.device.connect_out(out_addr) |
|
49 | self.device.connect_out(out_addr) |
@@ -216,8 +216,11 b' class KernelApp(BaseIPythonApplication):' | |||||
216 | self.stdin_socket = context.socket(zmq.ROUTER) |
|
216 | self.stdin_socket = context.socket(zmq.ROUTER) | |
217 | self.stdin_port = self._bind_socket(self.stdin_socket, self.stdin_port) |
|
217 | self.stdin_port = self._bind_socket(self.stdin_socket, self.stdin_port) | |
218 | self.log.debug("stdin ROUTER Channel on port: %i"%self.stdin_port) |
|
218 | self.log.debug("stdin ROUTER Channel on port: %i"%self.stdin_port) | |
219 |
|
219 | |||
220 | self.heartbeat = Heartbeat(context, (self.ip, self.hb_port)) |
|
220 | # heartbeat doesn't share context, because it mustn't be blocked | |
|
221 | # by the GIL, which is accessed by libzmq when freeing zero-copy messages | |||
|
222 | hb_ctx = zmq.Context() | |||
|
223 | self.heartbeat = Heartbeat(hb_ctx, (self.ip, self.hb_port)) | |||
221 | self.hb_port = self.heartbeat.port |
|
224 | self.hb_port = self.heartbeat.port | |
222 | self.log.debug("Heartbeat REP Channel on port: %i"%self.hb_port) |
|
225 | self.log.debug("Heartbeat REP Channel on port: %i"%self.hb_port) | |
223 |
|
226 |
General Comments 0
You need to be logged in to leave comments.
Login now