如何检测Tcl线程fileevent或脚本之后的错误

时间:2016-01-28 15:01:42

标签: tcl

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

  1. 同步线程::发送,线程中的立即错误
  2. 同步线程::发送,脚本后的线程错误
  3. 异步线程::发送,线程中的立即错误
  4. 异步线程::发送,脚本后的线程错误
  5. 我在测试线程中使用了一个after命令来(希望)模仿一个fileevent脚本。正如预期的那样,通过catch :: send命令的catch捕获case 1线程错误,并且thread :: errorproc过程和我的自定义bgerror过程捕获了case 3线程错误。案例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
    

    我正在使用Tcl 8.5和Ubuntu 10.04 LTS。

    对于如何检测线程的fileevent或脚本之后发生的错误,您有任何其他建议吗?

    的问候,
    smercer

0 个答案:

没有答案