TkInter在通过gRPC调用时崩溃

2024-09-30 12:19:40 发布

您现在位置:Python中文网/ 问答频道 /正文

设置

  • 大苏尔马科斯酒店
  • Python 3.9.5
  • 主要依赖项
grpcio = "^1.41.0"
grpcio-tools = "^1.41.0"
grpcio-reflection = "^1.41.0"

问题

我有一个使用TkInter的简单Python脚本,它在命令行模式下工作,但在使用gRPC调用模块时崩溃

代码

TkInter相关代码:

import tkinter as tk
import tkinter.filedialog as tkfiledialog

def main():
    root = tk.Tk()
    
    root.withdraw()
    root.after_idle(prompt, root)
    root.mainloop()

def prompt(root):
    return tkfiledialog.askopenfilename(
        parent=root,
        title="Select Files",
        filety[es=[("All Files", "*")],
        defaultextension=("All Files", "*"),
        multiple=True,
    ) 

gRPC架构非常标准,我认为不值得发布。 它与我的客户端实现也没有什么关系,因为我可以使用grpcurl轻松地重现崩溃


grpcurl -d '{"dryrun": false, "verbose": false, "startdir": ".", "dironly": false, "filepatterns": "*" }' -plaintext localhost:57728 selectfilesfolders.SelectFilesFolders.SelectFilesFolders

事故日志

2021-10-10 16:06:50.147 Python[2855:90390] WARNING: NSWindow drag regions should only be invalidated on the Main Thread! This will throw an exception in the future. Called from (
    0   AppKit                              0x00007fff22e55ed1 -[NSWindow(NSWindow_Theme) _postWindowNeedsToResetDragMarginsUnlessPostingDisabled] + 352
    1   AppKit                              0x00007fff22e40aa2 -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 1296
    2   AppKit                              0x00007fff23002c2f -[NSPanel _initContent:styleMask:backing:defer:contentView:] + 50
    3   AppKit                              0x00007fff22e4058b -[NSWindow initWithContentRect:styleMask:backing:defer:] + 42
    4   AppKit                              0x00007fff23002be4 -[NSPanel initWithContentRect:styleMask:backing:defer:] + 64
    5   AppKit                              0x00007fff2384e274 -[NSSavePanel initWithContentRect:styleMask:backing:defer:] + 97
    6   AppKit                              0x00007fff2385636d -[NSOpenPanel initWithContentRect:styleMask:backing:defer:] + 151
    7   AppKit                              0x00007fff2314f0e5 -[NSPanel init] + 75
    8   AppKit                              0x00007fff2384e1f0 -[NSSavePanel init] + 197
    9   AppKit                              0x00007fff23522c3a +[NSSavePanel(Instantiation) _crunchyRawUnbonedPanel] + 58
    10  libtk8.6.dylib                      0x0000000102b97a11 Tk_GetOpenFileObjCmd + 67
    11  libtcl8.6.dylib                     0x00000001029886dc TclNRRunCallbacks + 80
    12  _tkinter.cpython-39-darwin.so       0x0000000102961029 Tkapp_Call + 585
    13  Python                              0x000000010123245d cfunction_call + 125
    14  Python                              0x00000001011f3a3c _PyObject_Call + 140
    15  Python                              0x00000001012c7a73 _PyEval_EvalFrameDefault + 27027
    16  Python                              0x00000001012cab33 _PyEval_EvalCode + 2611
    17  Python                              0x00000001011f3c41 _PyFunction_Vectorcall + 289
    18  Python                              0x00000001012c9e3c call_function + 732
    19  Python                              0x00000001012c7342 _PyEval_EvalFrameDefault + 25186
    20  Python                              0x00000001012cab33 _PyEval_EvalCode + 2611
    21  Python                              0x00000001011f3c41 _PyFunction_Vectorcall + 289
    22  Python                              0x00000001012c9e3c call_function + 732
    23  Python                              0x00000001012c7491 _PyEval_EvalFrameDefault + 25521
    24  Python                              0x00000001011f3cb8 function_code_fastcall + 104
    25  Python                              0x00000001011f5de9 method_vectorcall + 441
    26  Python                              0x00000001012c7a73 _PyEval_EvalFrameDefault + 27027
    27  Python                              0x00000001012cab33 _PyEval_EvalCode + 2611
    28  Python                              0x00000001011f3c41 _PyFunction_Vectorcall + 289
    29  Python                              0x00000001012c7a73 _PyEval_EvalFrameDefault + 27027
    30  Python                              0x00000001012cab33 _PyEval_EvalCode + 2611
    31  Python                              0x00000001011f3c41 _PyFunction_Vectorcall + 289
    32  Python                              0x00000001011f5d42 method_vectorcall + 274
    33  _tkinter.cpython-39-darwin.so       0x0000000102963bb1 PythonCmd + 209
    34  libtcl8.6.dylib                     0x00000001029886dc TclNRRunCallbacks + 80
    35  libtcl8.6.dylib                     0x0000000102a54ed3 AfterProc + 83
    36  libtcl8.6.dylib                     0x0000000102a54570 TclServiceIdle + 87
    37  libtcl8.6.dylib                     0x0000000102a37d27 Tcl_DoOneEvent + 349
    38  libtk8.6.dylib                      0x0000000102b1aa02 MapFrame + 40
    39  libtcl8.6.dylib                     0x0000000102a54570 TclServiceIdle + 87
    40  libtcl8.6.dylib                     0x0000000102a37d27 Tcl_DoOneEvent + 349
    41  _tkinter.cpython-39-darwin.so       0x00000001029633de _tkinter_tkapp_mainloop + 382
    42  Python                              0x00000001011fc3df method_vectorcall_FASTCALL + 335
    43  Python                              0x00000001012c9e3c call_function + 732
    44  Python                              0x00000001012c7342 _PyEval_EvalFrameDefault + 25186
    45  Python                              0x00000001012cab33 _PyEval_EvalCode + 2611
    46  Python                              0x00000001011f3c41 _PyFunction_Vectorcall + 289
    47  Python                              0x00000001011f5cfa method_vectorcall + 202
    48  Python                              0x00000001012c9e3c call_function + 732
    49  Python                              0x00000001012c7363 _PyEval_EvalFrameDefault + 25219
    50  Python                              0x00000001011f3cb8 function_code_fastcall + 104
    51  Python                              0x00000001012c9e3c call_function + 732
    52  Python                              0x00000001012c7342 _PyEval_EvalFrameDefault + 25186
    53  Python                              0x00000001011f3cb8 function_code_fastcall + 104
    54  Python                              0x00000001012c7a73 _PyEval_EvalFrameDefault + 27027
    55  Python                              0x00000001012cab33 _PyEval_EvalCode + 2611
    56  Python                              0x00000001011f3c41 _PyFunction_Vectorcall + 289
    57  Python                              0x00000001012c9e3c call_function + 732
    58  Python                              0x00000001012c7363 _PyEval_EvalFrameDefault + 25219
    59  Python                              0x00000001011f3cb8 function_code_fastcall + 104
    60  Python                              0x00000001011f5cfa method_vectorcall + 202
    61  Python                              0x00000001012c9e3c call_function + 732
    62  Python                              0x00000001012c73fb _PyEval_EvalFrameDefault + 25371
    63  Python                              0x00000001012cab33 _PyEval_EvalCode + 2611
    64  Python                              0x00000001011f3c41 _PyFunction_Vectorcall + 289
    65  Python                              0x00000001012c9e3c call_function + 732
    66  Python                              0x00000001012c73fb _PyEval_EvalFrameDefault + 25371
    67  Python                              0x00000001011f3cb8 function_code_fastcall + 104
    68  Python                              0x00000001012c7a73 _PyEval_EvalFrameDefault + 27027
    69  Python                              0x00000001011f3cb8 function_code_fastcall + 104
    70  Python                              0x00000001012c9e3c call_function + 732
    71  Python                              0x00000001012c7342 _PyEval_EvalFrameDefault + 25186
    72  Python                              0x00000001011f3cb8 function_code_fastcall + 104
    73  Python                              0x00000001012c7a73 _PyEval_EvalFrameDefault + 27027
    74  Python                              0x00000001011f3cb8 function_code_fastcall + 104
    75  Python                              0x00000001012c9e3c call_function + 732
    76  Python                              0x00000001012c7342 _PyEval_EvalFrameDefault + 25186
    77  Python                              0x00000001011f3cb8 function_code_fastcall + 104
    78  Python                              0x00000001012c9e3c call_function + 732
    79  Python                              0x00000001012c7342 _PyEval_EvalFrameDefault + 25186
    80  Python                              0x00000001011f3cb8 function_code_fastcall + 104
    81  Python                              0x00000001011f5d42 method_vectorcall + 274
    82  Python                              0x000000010136ec56 t_bootstrap + 70
    83  Python                              0x0000000101320169 pythread_wrapper + 25
    84  libsystem_pthread.dylib             0x00007fff2052c8fc _pthread_start + 224
    85  libsystem_pthread.dylib             0x00007fff20528443 thread_start + 15
)

变通办法

  • 如果我用任何代码替换TkInter部分,一切正常
  • 通过子进程调用IPC也可以

问题:

我应该如何进行调试,还是这表明TkInter不适合我的任务


Tags: tkintercodefunctionrootcalldylibappkitpyeval
1条回答
网友
1楼 · 发布于 2024-09-30 12:19:40

根据this GitHub anwser

这可能是macOS特定的线程问题

On the other hand, according to tkinter's doc. The library may have special event handling logic and threading restrictions, and gRPC Python uses a thread pool to handle incoming requests with gRPC Core handling the IO.

通过深入研究那个医生,我们发现

A Python interpreter may have many threads associated with it. In Tcl, multiple threads can be created, but each thread has a separate Tcl interpreter instance associated with it. Threads can also create more than one interpreter instance, though each interpreter instance can be used only by the one thread that created it.

Each Tk object created by tkinter contains a Tcl interpreter. It also keeps track of which thread created that interpreter. Calls to tkinter can be made from any Python thread. Internally, if a call comes from a thread other than the one that created the Tk object, an event is posted to the interpreter’s event queue, and when executed, the result is returned to the calling Python thread.

虽然我不是特定于平台的线程模型专家,但我知道macOS使用的是“Grand Central Dispatch”任务队列系统,它隐藏了大量线程池细节,这与Windows不同

因此,如果不深入研究gRPC的线程池模型,我不能说从易失性gRPC的I/O线程调用Tkinter小部件是安全的,Tkinter小部件跟踪创建它们的线程

相关问题 更多 >

    热门问题