【问题标题】:exiting out Tcl_DoOneEvent function退出 Tcl_DoOneEvent 函数
【发布时间】:2016-06-20 07:25:48
【问题描述】:

我有来自 C++ 文件的 TCL 文件。 为此,我最终使用了 Tcl_DoOneEvent 函数来处理所有 TCL 调用。 我在 Main 函数中也调用了一些线程。为了退出所有线程和函数,我编写了一个退出函数。所以在当前情况下,我看到除了最后调用的 Tcl_DoOneEvent 函数之外,所有 pthread 和其他函数都被终止。这给出了一个分割错误。 有没有办法从其他函数中退出 while(1) 函数。

main()
{
...
...
pthread_create(thread1);
pthread_create(thread2);
while(1) Tcl_DoOneEvent(TCL_ALL_EVENTS);
return(0);
}

quit_fn()
{
...
...
pthread_cancel(thread1);
pthread_cancel(thread2);
...
// exit(0) ; ->  this also results in segmentation error 
}

【问题讨论】:

    标签: c++ segmentation-fault pthreads tcl


    【解决方案1】:

    为了退出while循环,你应该改变循环的条件,让它依赖一个你可以从另一个线程改变的变量(声明它为volatile)。

    volatile bool exitLoop = false;
    
    while (!exitLoop) 
    {
        Tcl_DoOneEvent(TCL_ALL_EVENTS);
    }
    

    我不确定,但如果没有更多事件,这可能会被无限期阻止。两种可能的解决方案可能是使用 TCL_DONT_WAIT 标志:

    Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
    // sleep some time here in order to avoid busy wait
    

    或者更好的是,从您的退出函数触发一个事件,以便唤醒 Tcl_DoOneEvent,并且在下一次迭代中您的 exitLoop 变量为真。

    最后,我建议您对所有线程都遵循相同的循环和退出条件方法。不要使用 pthread_cancel 来完成线程,而是尝试使用 pthread_join。这样您就可以准确控制线程退出的时间点,并且可以进行一些清理并避免分段错误或其他类型的错误。

    【讨论】:

    • 让退出函数向主线程发送事件是推荐的方法。事件可以有一个简单的处理程序,或者事件处理程序可以是设置exitLoop,然后不需要是volatile,因为它只能从一个线程访问。 TCL_DONT_WAIT 不推荐用于此用例;没有它,Tcl 可以有效地为事件休眠。
    • 我同意这一点,发送一个事件并让 Tcl 处理睡眠会更好。不需要 volatile,前提是其他线程从未使用过该标志(但我们不知道代码中是否是这种情况)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    • 1970-01-01
    • 2011-12-07
    • 2011-02-07
    • 2015-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多