Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 在ipython/jupyter笔记本中运行单元格的新线程_Multithreading_Ipython_Ipython Notebook_Jupyter - Fatal编程技术网

Multithreading 在ipython/jupyter笔记本中运行单元格的新线程

Multithreading 在ipython/jupyter笔记本中运行单元格的新线程,multithreading,ipython,ipython-notebook,jupyter,Multithreading,Ipython,Ipython Notebook,Jupyter,有时运行单个单元格需要很长时间,当它运行时,我希望在同一个笔记本中编写和运行其他单元格,在相同的上下文中访问变量 是否可以使用ipython magic,当它被添加到单元格中时,运行单元格将自动创建一个新线程,并在笔记本中使用共享的全局数据运行?这可能不是答案,而是指向它的方向。我没有看到这样的东西,但我对这个也很感兴趣 我目前的发现表明,人们需要定义自己的自定义细胞魔法。很好的参考资料是文档中的自定义单元格魔术部分,以及我将考虑的两个示例: memit:IPython的神奇内存使用率测试 演

有时运行单个单元格需要很长时间,当它运行时,我希望在同一个笔记本中编写和运行其他单元格,在相同的上下文中访问变量


是否可以使用ipython magic,当它被添加到单元格中时,运行单元格将自动创建一个新线程,并在笔记本中使用共享的全局数据运行?

这可能不是答案,而是指向它的方向。我没有看到这样的东西,但我对这个也很感兴趣

我目前的发现表明,人们需要定义自己的自定义细胞魔法。很好的参考资料是文档中的自定义单元格魔术部分,以及我将考虑的两个示例:

  • memit:IPython的神奇内存使用率测试
  • 演示Python多线程与多处理:
这两个链接都将代码包装在一个线程中。这可能是一个起点

更新:github上的ngcm教程包含背景作业类的说明

##github.com/jupyter/ngcm tutorial/blob/master/Day-1/IPython%20Kernel/Background%20Jobs.ipynb
从IPython.lib将后台作业作为bg导入
jobs=bg.BackgroundJobManager()
def printfunc(间隔=1,重复次数=5):
对于范围内的n(重复次数):
睡眠时间(间隔)
打印('在后台…%i“%n”)
sys.stdout.flush()
打印('全部完成!')
sys.stdout.flush()
jobs.new('printfunc(1,3)')
jobs.status()
更新2:另一个选项:

从IPython.display导入显示
从ipywidgets导入IntProgress
导入线程
类应用程序(对象):
定义初始值(自,nloops=2000):
self.nloops=nloops
self.pb=IntProgress(description='Thread loops',min=0,max=self.nloops)
def启动(自):
显示(self.pb)
当self.pb.value
这是我想到的一个小片段

def jobs_manager():
    from IPython.lib.backgroundjobs import BackgroundJobManager
    from IPython.core.magic import register_line_magic
    from IPython import get_ipython

    jobs = BackgroundJobManager()

    @register_line_magic
    def job(line):
        ip = get_ipython()
        jobs.new(line, ip.user_global_ns)

    return jobs
它使用IPython内置模块
IPython.lib.backgroundjobs
。所以代码小而简单,并且没有引入新的依赖项

我是这样使用它的:

jobs = jobs_manager()

%job [fetch_url(_) for _ in urls]  # saves html file to disk
Starting job # 0 in a separate thread.
%job [fetch_url(_) for _ in log_progress(urls, every=1)]
然后,您可以通过以下方式监控状态:

jobs.status()

Running jobs:
1 : [fetch_url(_) for _ in urls]

Dead jobs:
0 : [fetch_url(_) for _ in urls]
如果作业失败,您可以使用检查堆栈跟踪

jobs.traceback(0)
没有办法杀死一份工作。所以我小心地使用这个肮脏的黑客:

def kill_thread(thread):
    import ctypes

    id = thread.ident
    code = ctypes.pythonapi.PyThreadState_SetAsyncExc(
        ctypes.c_long(id),
        ctypes.py_object(SystemError)
    )
    if code == 0:
        raise ValueError('invalid thread id')
    elif code != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(
            ctypes.c_long(id),
            ctypes.c_long(0)
        )
        raise SystemError('PyThreadState_SetAsyncExc failed')
它在给定线程中引发
SystemError
。所以我要杀了一份工作

kill_thread(jobs.all[1])
把我做的所有跑步工作都干掉

for thread in jobs.running:
    kill_thread(thread)
我喜欢将
%job
与基于小部件的进度条一起使用,如下所示:

jobs = jobs_manager()

%job [fetch_url(_) for _ in urls]  # saves html file to disk
Starting job # 0 in a separate thread.
%job [fetch_url(_) for _ in log_progress(urls, every=1)]

人们甚至可以使用
%job
而不是
多处理

for chunk in get_chunks(urls, 3):
    %job [fetch_url(_) for _ in log_progress(chunk, every=1)]

此代码存在一些明显的问题:

  • 您不能在
    %job
    中使用任意代码。例如,可以没有作业,也可以没有打印。所以我将其用于在硬盘上存储结果的例程

  • 有时,
    kill_-thread
    中的肮脏黑客攻击不起作用。我认为这就是为什么
    IPython.lib.backgroundjobs
    在设计上没有这个功能的原因。如果线程正在执行一些系统调用,如
    睡眠
    读取
    异常将被忽略

  • 它使用线程。Python有GIL,因此
    %job
    不能用于一些需要Python字节码的繁重计算


  • @minrk请你看看这个答案,看看这个解决方案是否还有我没有想到的其他问题?什么是“你不能使用任意代码”?我正在尝试制作一个后台作业,用从磁盘打开的图像更新屏幕。我还注意到,
    time.sleep
    “完成”了线程。回答得真棒!多年来一直在寻找这样的东西