如何检测Tcl线程fileevent或after脚本中的错误

如何检测Tcl线程fileevent或after脚本中的错误,tcl,Tcl,在我的主线程中,我试图检测并响应工作线程的fileevent脚本中发生的错误。我编写了一个测试脚本,试图在四种情况下检测线程错误: 同步线程::发送,线程中的即时错误 同步线程::发送,脚本后的线程出错 异步线程::发送,线程中的立即错误 异步线程::发送,脚本后的线程出错 我在测试线程中使用after命令(希望)模拟fileevent脚本。正如预期的那样,案例1线程错误是通过thread::send命令捕获的,案例3线程错误是由thread::errorproc过程和我的自定义bgerro过程

在我的主线程中,我试图检测并响应工作线程的fileevent脚本中发生的错误。我编写了一个测试脚本,试图在四种情况下检测线程错误:

  • 同步线程::发送,线程中的即时错误
  • 同步线程::发送,脚本后的线程出错
  • 异步线程::发送,线程中的立即错误
  • 异步线程::发送,脚本后的线程出错
  • 我在测试线程中使用after命令(希望)模拟fileevent脚本。正如预期的那样,案例1线程错误是通过thread::send命令捕获的,案例3线程错误是由thread::errorproc过程和我的自定义bgerro过程捕获的。案例2和案例4的线程错误反映在主线程中,但我似乎无法通过自定义过程捕获它们

    以下是我的测试脚本:

        #!/usr/bin/env tclsh
    
    
        package require Thread;
    
    
        # Custom error handling procedure for errors during asynchronous thread::send
        proc error_proc {id error} {
                puts "\n---------- error_proc: $id $error **********\n";
        }
        thread::errorproc error_proc;
    
    
        # Custom error and bgerror procedures to try to see the thread error
        rename error original_error;
        proc error {err} {
                puts "---------- error: $err\n";
        }
        proc bgerror {err} {
                puts "---------- bgerror: $err\n";
        }
    
    
        # Non-blocking wait procedure to keep the output in order
        proc waitms {ms} {
                set ::done 0;
                after $ms {set ::done 1};
                vwait ::done;
        }
    
    
        # Create the worker thread
        set tid [thread::create {
    
                proc test_error_immediately {s} {
                        error "test_error_immediately ($s)";
                }
    
                proc test_error_after {ms s} {
                        after $ms [list error "test_error_after ($s)"];
                }
    
                thread::wait;
    
                puts "---------- Exiting thread";
        }]
    
    
        # Test case 1 - synchronous thread::send, immediate error
        if {[catch {thread::send $tid [list test_error_immediately "Case 1"]} result]} {
                set state "ERROR";
        } else {
                set state "OK";
        }
        puts "---------- Synchronous test_error_immediately $state ($result)\n"
    
    
        # Test case 2 - synchronous thread::send, error in thread after script
        if {[catch {thread::send $tid [list test_error_after 1000 "Case 2"]} result]} {
                set state "ERROR";
        } else {
                set state "OK";
        }
        puts "---------- Synchronous test_error_after $state ($result)\n";
    
    
        # Wait so that the output is in order
        waitms 1500;
    
    
        # Test case 3 - asynchronous thread::send, immediate error
        if {[catch {thread::send -async $tid [list test_error_immediately "Case 3"] result} catch_result]} {
                set state "ERROR";
                set result $catch_result;
        } else {
                set state "OK";
                vwait result;
        }
        puts "---------- Asynchronous test_error_immediately $state ($result)\n";
    
    
        # Wait so that the output is in order
        waitms 100;
    
    
        # Test case 4 - asynchronous thread::send, error in thread after script
        if {[catch {thread::send -async $tid [list test_error_after 1000 "Case 4"] result} catch_result]} {
                set state "ERROR";
                set result $catch_result;
        } else {
                set state "OK";
                vwait result;
        }
        puts "---------- Asynchronous test_error_after $state ($result)\n";
    
    
        # Clean up
        if {[thread::exists $tid]} {
    
                after 2000 {
                        thread::release $::tid;
                        puts "\n---------- $::tid released\n";
                }
        }
    
    
        puts "---------- Waiting forever ...\n";
    
    
        vwait forever;
    
    以下是我的计算机上的输出:

        ---------- Synchronous test_error_immediately ERROR (test_error_immediately (Case 1))
    
        ---------- Synchronous test_error_after OK (after#0)
    
        test_error_after (Case 2)
            while executing
        "error {test_error_after (Case 2)}"
            ("after" script)
    
        ---------- error_proc: tid0x7f5673e9d700 test_error_immediately (Case 3)
            while executing
        "error "test_error_immediately ($s)""
            (procedure "test_error_immediately" line 2)
            invoked from within
        "test_error_immediately {Case 3}" **********
    
        ---------- Asynchronous test_error_immediately OK (test_error_immediately (Case 3))
    
        ---------- bgerror: test_error_immediately (Case 3)
    
        ---------- Asynchronous test_error_after OK (after#1)
    
        ---------- Waiting forever ...
    
        test_error_after (Case 4)
            while executing
        "error {test_error_after (Case 4)}"
            ("after" script)
    
        ---------- tid0x7f5673e9d700 released
    
        ---------- Exiting thread
    
    我使用的是TCL8.5和Ubuntu10.04LTS

    对于如何检测线程的fileevent或after脚本中发生的错误,您还有其他建议吗

    问候,

    斯默塞

    tl;博士,请看并感谢@glennjackman的指点,我为我冗长的原创(也是第一次)帖子道歉。