致命的 Python 错误:无法获取随机数来初始化 Python
Fatal Python error: failed to get random numbers to initialize Python
Fatal Python 错误:无法获取随机数来初始化 Python
环境窗口 10, VSC 15
使用 CreateProcessA winapi 并传递 lpenvironment 变量来运行带有脚本的 python。 当 LPENVIRONMENT 传递 NULL 时,它工作正常。 如果我设置环境变量 PATH 和 PYTHONPATH = "paths",并传递该 LPSTR(env.c_Str(((,它会在运行时抛出上述错误。 python版本是3.5.6
有什么帮助吗?
更多细节。
- 我使用 CreateProcessA WINAPI 运行子进程 python.exe"C:\Program Files\endpoint\Python_ML\mlprocessor_server.py"。
- 我想使用两个环境变量"PYTHONPATH"和"PATH"运行子进程。 PYTHONPATH="C:\Program Files\endpoint\Python";"C:\Program Files\endpoint\Python\Scripts";"C:\Program Files\endpoint\Python\include";"C:\Program Files\endpoint\Python\Lib";"C:\Program Files\endpoint\Python\libs";"C:\Program Files\endpoint\Python\Lib\site-packages";"C:\程序文件\端点\Python_ML" PATH="C:\Program Files\endpoint\Python";"C:\Program Files\endpoint\Python\Lib";"C:\Program Files\endpoint\Python\Scripts";"C:\Program Files\endpoint\Python\libs">
由于某种原因,CreateProcessA 中的第 7 个参数失败,如果 python.exe为空,则成功运行,否则它会打印"致命的 Python 错误:无法获取随机数来初始化 Python"。
我设置参数的方式如下...
std::string Base = Configuration::getBasePath((;
std::string environPython = Base;
environPython.append("\Python;");
environPython.append(Base);
environPython.append("\Python\Scripts;");
environPython.append(Base);
environPython.append("\Python\include;");
environPython.append(Base);
environPython.append("\Python\Lib;");
environPython.append(Base);
environPython.append("\Python\libs;");
environPython.append(Base);
environPython.append("\Python\Lib\site-packages;");
environPython.append(Base);
environPython.append("\Python\_ML;");
environPython.push_back(' ');
std::string environPath = Base;
environPath.append("\Python;");
environPath.append(Base);
environPath.append("\Python\Lib;");
environPath.append(Base);
environPath.append("\Python\Scripts;");
environPath.append(Base);
environPath.append("\Python\libs;");
environPath.push_back(' ');
std::string cmd = Base;
cmd.append("\Python\python.exe");
std::string params = """;
params.append(cmd);
params.append("" "");
params.append(Base);
params.append("\Python\_ML\mlprocessor_server.py"");
std::map env = { { "PYTHONPATH", environPython.data(( }, { "PATH", environPath.data(( }};
// example for generating block of strings
std::vector<char> envBlock;
std::for_each(env.begin(), env.end(),
[&envBlock](const std::pair<std::string, std::string> & p) {
std::copy(p.first.begin(), p.first.end(), std::back_inserter(envBlock));
envBlock.push_back('=');
std::copy(p.second.begin(), p.second.end(), std::back_inserter(envBlock));
envBlock.push_back(' ');
}
);
envBlock.push_back(' ');
// feed this into ::CreateProcess()
LPVOID lpEnvironment = (LPVOID)envBlock.data();
bool result = CreateProcessA(cmd.c_str(), (LPSTR)params.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, lpEnvironment, NULL, &info, &pi);
结果总是正确的,python.exe没有显示在任务管理器中,并给出致命的Python错误:无法获取随机数来初始化Python。
如果 lpEnvironment 为 NULL,python.exe 将显示在任务管理器中。
您传递给CreateProcessA
的环境必须包含SYSTEMROOT
,否则在初始化期间在 python 内部调用 Win32 API 调用CryptAcquireContext
将失败。
当以 lpEnvironment 形式传入 NULL 时,新进程将继承已定义SYSTEMROOT
调用进程的环境。
为了跟进一个例子,如何在现实世界中的纯Python软件中非常容易地触发它,有时Python打开自己的实例来执行某些任务很有用,其中子任务需要设置特定的PYTHONPATH
。 通常,这可以在不那么挑剔的平台(即不是Windows(上懒惰地完成,如下所示:
import sys
from subprocess import Popen
p = Popen([sys.executable, '-c', 'print("hello world")'], env={
'PYTHONPATH': '', # set it to somewhere
})
但是,在 Windows 上这样做将导致以下令人困惑的失败:
Python 3.8.10 (...) [MSC v.1928 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> from subprocess import Popen
>>> p = Popen([sys.executable, '-c', 'print("hello world")'], env={
... 'PYTHONPATH': ''
... })
Fatal Python error: _Py_HashRandomization_Init: failed to get random numbers to initialize Python
Python runtime state: preinitialized
解决方法很明显:克隆os.environ
以确保SYSTEMROOT
到位,从而避免@Joe Savage的答案指出的问题,例如:
>>> import os
>>> env = os.environ.copy()
>>> env['PYTHONPATH'] = ''
>>> p = Popen([sys.executable, '-c', 'print("hello world")'], env=env)
hello world
需要此类修复的实际示例:
- Glean SDK
- LocalStack 的 aws 包装器
- 完善
-
setuptools
(仅在测试中,但可以作为一个例子,说明几乎任何人都可以轻易犯这个错误(。
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 整数不会重复超过随机数
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- Pybind11:将元组列表从Python传递到C++
- 如何在c++中使用引用实现类似python的行为
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 递归列出所有目录中的C++与Python与Ruby的性能
- IPC使用多个管道和分支进程来运行Python程序
- 从python中调用C++函数并获取返回值
- Python 3.7 和 excess_args 的 SWIG 问题
- Python中的for循环与C++有何不同
- 使用Pybind11向Python公开Eigen::张量
- if数组上的随机数
- 如何打开并写入一个名称取自C++中字符串的文件
- 致命的 Python 错误:无法获取随机数来初始化 Python
- 在 Python/C++ 中用更改文件中的随机数替换数字
- C++ 和 Python 实现之间的不同伪随机数
- 如何在C ++(qt)代码中使用python脚本?(网页抓取方面)
- Boost.python 将对象拉取到本地范围内以进行读取访问
- 用C++或Python生成随机数