Closed AnzhiZhang closed 1 year ago
不是插件线程什么的问题,感觉更像是python自己处理deamon线程跟stdin的问题 然后,依旧,求稳定复现方法
BUG.zip 我使用的整合,用常规的应该也可以 系统环境Win10 64, Python 3.8
stop
关服时报错联系MCSM同样报错猜测与MCDR被套娃有关
完整控制台截图
用C#窗体应用写了个套娃机,好像没有出现问题
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
namespace test
{
public partial class Form1 : Form
{
private Process process;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
process = new Process();
process.StartInfo.UseShellExecute = false; // 是否使用外壳程序
process.StartInfo.CreateNoWindow = true; //是否在新窗口中启动该进程的值
process.StartInfo.RedirectStandardInput = true; // 重定向输入流
process.StartInfo.RedirectStandardOutput = true; //重定向输出流
process.StartInfo.RedirectStandardError = true; //重定向错误流
process.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
process.Start();
process.StandardInput.WriteLine("J:");
process.StandardInput.WriteLine("cd J:/MCDReforged-0.6.3-alpha");
process.StandardInput.WriteLine("python MCDReforged.py");
backgroundWorker1.RunWorkerAsync();
}
private void button1_Click(object sender, EventArgs e)
{
process.StandardInput.WriteLine(textBox1.Text);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string str = process.StandardOutput.ReadLine();
e.Result = str;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (process.HasExited == false)
{
backgroundWorker1.RunWorkerAsync();
List<string> l = textBox2.Lines.ToList<string>();
l.Add(e.Result as string);
textBox2.Lines = l.ToArray();
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
process.Close();
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
textBox2.SelectionStart = textBox2.Text.Length;
textBox2.ScrollToCaret();
}
}
}
可能是我套娃的方式不对?
可能是我套娃的方式不对?
试试PyCharm和MCSManager
关闭MCDR的控制台线程 disable_console_thread: true
也不会引发错误,参考报错信息 Fatal Python error: could not acquire lock for <_io.BufferedReader name='<stdin>'> at interpreter shutdown, possibly due to daemon threads
猜测是控制台输入的问题
我知道出问题的地方在哪,我也会用pycharm,也没有遇到过此错误 无法 稳定 复现该问题,这也是该issue无法解决的原因
文件太大发不上来,这里有一份http://tmp.link/f/5f45ddfa142e1,群文件里也有
请了两人使用该文件尝试,有一人成功复现,另一人没有,也许与系统环境有关系,可能需要更多人尝试复现并反馈
我的环境 Win10专业版 64
, Python 3.8.3
, MCDR0.9.5
CPU信息
方法
1.解压
2.运行start.bat
3.根据需要修改.\server\server_core\MCDR\start.bat用于启动MCDR
4.浏览器打开http://127.0.0.1:23333
5.账号 #master
, 密码 123456
6.进入服务端管理
7.选择管理
8.选择命令控制台
9.开启MCDR
10.启动完成后输入stop发送关闭服务器
11.关闭后就出现了
这两位的复现结果
我也会报错,以前pycharm跑源码也会这个报错
有可能是 MCDR 在退出时未终止输入线程的循环,导致继续尝试 input
所引发的,可以试一下 issue/47
分支的构建
https://github.com/Fallen-Breath/MCDReforged/actions/runs/1138028987
有可能是 MCDR 在退出时未终止输入线程的循环,导致继续尝试
input
所引发的,可以试一下issue/47
分支的构建https://github.com/Fallen-Breath/MCDReforged/actions/runs/1138028987
使用action提供的构建,没有解决问题,但是报错似乎变了
我尝试了issue/47 分支的源码下载,也是报错 嗯对了最新版的源码也一样
是否跟这个issue有关系? https://bugs.python.org/issue26037
是否跟这个issue有关系? https://bugs.python.org/issue26037
应该与这个 issue 是有关系的,即 https://github.com/python/cpython/issues/70225 。python 在 daemon 线程里读 stdin 就有可能出问题
对于 pycharm 下的出现问题,可以参考这个 issue:https://youtrack.jetbrains.com/issue/PY-43748
复现脚本:
# test_input.py
import sys
import threading
import time
threading.Thread(target=lambda: eval(sys.argv[1]), daemon=True).start()
time.sleep(0.1)
测试脚本:
# test_input_batch.py
import subprocess
methods = [
'input()',
'sys.stdin.readline()',
'sys.stdin.buffer.readline()',
'sys.stdin.buffer.raw.readline()',
]
for m in methods:
print('======', m, '======')
ret = subprocess.call('python test_input.py "{}"'.format(m), shell=True)
print('====== ret', ret, '======')
print()
简单套壳实现
# wrapper.py
import subprocess
proc = subprocess.Popen('python -u test_input_batch.py', universal_newlines=True, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in proc.stdout:
print(line, end='')
在 Windows 10 + Python 3.9.12 + Pycharm 2023.1.2 下测试:
环境 | input() |
sys.stdin.readline() |
sys.stdin.buffer.readline() |
sys.stdin.buffer.raw.readline() |
---|---|---|---|---|
pycharm, 直接运行 | 出错 | 正常 | 出错 | 正常 |
pycharm, emulate terminal | 正常 | 正常 | 出错 | 正常 |
cmd | 正常 | 正常 | 出错 | 正常 |
powershell | 正常 | 正常 | 出错 | 正常 |
python wrapper.py |
出错 | 正常 | 出错 | 正常 |
其中直接运行 pycharm、运行 python wrapper.py
的输出如下
====== input() ======
Fatal Python error: _enter_buffered_busy: could not acquire lock for <_io.BufferedReader name='<stdin>'> at interpreter shutdown, possibly due to daemon threads
Python runtime state: finalizing (tstate=000001B521D70FF0)
Current thread 0x00006e24 (most recent call first):
<no Python frame>
====== ret 3221225477 ======
====== sys.stdin.readline() ======
====== ret 0 ======
====== sys.stdin.buffer.readline() ======
Fatal Python error: _enter_buffered_busy: could not acquire lock for <_io.BufferedReader name='<stdin>'> at interpreter shutdown, possibly due to daemon threads
Python runtime state: finalizing (tstate=000001CA73D20780)
Current thread 0x00007f04 (most recent call first):
<no Python frame>
====== ret 3221225477 ======
====== sys.stdin.buffer.raw.readline() ======
====== ret 0 ======
不同从 stdin 读取的方式可能会有不一样的表现,这应该是有 cpython 底层实现的差异导致的
如果 MCDR 的输入输出流被接管(如 pycharm 直接运行、其他程序套壳运行),input()
的表现可能会发生变化,并有可能导致该 issue 发生
可以考虑用 sys.stdin.readline()
替代 console_handler.py
里在 daemon 线程调用的 input()
?
启用 advanced_console
后,不再有直接读 stdin 的操作,可能会抑制该 issue?不过在 MCDR 的输入输出流被接管的前提下,advanced_console
是得关掉的
好几个版本直接就见过了,今天又见到了,似乎是插件线程管理问题
File "D:\Project\Python\MCSManager_8.6.11_Win_x86\server\server_core\DevServer\utils\plugin_thread.py", line 33 in run