docker 中的 Python – RuntimeError: can't start new thread

Posted

技术标签:

【中文标题】docker 中的 Python – RuntimeError: can\'t start new thread【英文标题】:Python in docker – RuntimeError: can't start new threaddocker 中的 Python – RuntimeError: can't start new thread 【发布时间】:2022-01-02 07:51:02 【问题描述】:

我自己无法调试一个错误。我在 Fedora 版本 35(三十五)的 docker 映像中运行 python 3.8.12,我无法从 python 生成线程。 boto3 传输需要并行运行,它使用 concurrent.features 来执行此操作。

在没有任何依赖关系的情况下复制我的问题的最简单示例是 (copied from python docs)

import concurrent.futures
import urllib.request

URLS = ['http://www.foxnews.com/',
        'http://www.cnn.com/',
        'http://europe.wsj.com/',
        'http://www.bbc.co.uk/',
        'http://some-made-up-domain.com/']

def load_url(url, timeout):
    with urllib.request.urlopen(url, timeout=timeout) as conn:
        return conn.read()

with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
    future_to_url = executor.submit(load_url, url, 60): url for url in URLS
    for future in concurrent.futures.as_completed(future_to_url):
        url = future_to_url[future]
        try:
            data = future.result()
        except Exception as exc:
            pass

遗憾的是这些行的输出是

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 2, in <dictcomp>
  File "/usr/lib64/python3.8/concurrent/futures/thread.py", line 188, in submit
    self._adjust_thread_count()
  File "/usr/lib64/python3.8/concurrent/futures/thread.py", line 213, in _adjust_thread_count
    t.start()
  File "/usr/lib64/python3.8/threading.py", line 852, in start
    _start_new_thread(self._bootstrap, ())
RuntimeError: can't start new thread

这就是我所拥有的。有应该看的地方吗?我已经检查了ulimit,上面写着unlimited。我有点绝望在哪里寻找或改变什么来调试这个问题。

【问题讨论】:

【参考方案1】:

我知道这可能不是您要寻找的答案,但 Python 中的线程可能会出现问题(因为 GIL)。如果可以,请尝试使用ProcessPoolExecutor,它也适用于concurrent.futures。但是,我不知道 boto3 是否支持它。如果您从自定义代码中调用 boto3,那么应该很容易将线程替换为进程并查看是否有效。

【讨论】:

谢谢。我正在使用 django 存储,它在引擎盖下使用 boto3,它使用 s3transfer。我查看了源代码,也许可以替换它,但我需要找到这个问题的核心,因为几周前我在同一个运行的服务器上没有这些问题。【参考方案2】:

解决此问题的方法是将 docker 从版本 18.06.1-ce 升级到 20.10.7。

为什么?

这是因为 Docker 20.10.9 的默认 seccomp 配置文件未调整为支持 Ubuntu 21.10 和 Fedora 35 中采用的 glibc 2.34 的 clone() 系统调用包装器。

来源:ubuntu:21.10 and fedora:35 do not work on the latest Docker (20.10.9)

【讨论】:

以上是关于docker 中的 Python – RuntimeError: can't start new thread的主要内容,如果未能解决你的问题,请参考以下文章

使用 dbus 关闭 docker 容器和 python 中的树莓派

将参数传递给 Docker 容器中的 Python argparse

在不同的docker容器之间共享python中的变量

python:2.7-alpine 在 Docker 中的 psycopg2 安装

Python 3.4 Docker 容器中的 AWS Elastic Beanstalk container_commands

如何从 docker 容器中的 python 脚本连接到 localhost 上的 mysql 数据库