首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Tcl_LinkVar和Tcl_UpdateLinkedVar没有更新我的TCL变量

Tcl_LinkVar和Tcl_UpdateLinkedVar没有更新我的TCL变量
EN

Stack Overflow用户
提问于 2013-09-19 23:18:10
回答 1查看 202关注 0票数 0

我是C++的新手,也是TCL的新手。我正在尝试编写两个共享一个名为tValue的变量的应用程序(一个用C++编写,另一个用TCL编写)。

目标是C++程序请求用户输入并将该输入分配给tValue。然后,TCL程序应该更新它的tValue。

我已经找了又找,但找不到其他东西可以尝试。

编辑:最初tcl脚本是在“主”C++线程中执行的,但是C++线程等待tcl脚本完成。将调用tcl脚本的c++代码转移到自己的线程中确实允许两个线程的并发执行(这是实现这一点的唯一方法吗?),但是tValue仍然没有更新

以下是这两个程序的源代码:

test.cpp

代码语言:javascript
复制
#include <tcl.h>
#include <iostream>

using namespace std;

Tcl_Interp * interp = Tcl_CreateInterp();
char * tValue = Tcl_Alloc(20);

void *thread_proc(void* x);

int main() {

    cout << "C++: INIT: " << Tcl_Init(interp) << "\n";

    cout << "C++: I'm alive, I'm alive, I'M ALIVE!!!\n";

    pthread_t t1;
    int res = pthread_create(&t1,NULL,thread_proc,NULL);

    int errLink = Tcl_LinkVar (interp, tValue, (char *) &tValue, TCL_LINK_STRING);

    cout << "C++: INTERP " << errLink << "\n";

    usleep(5000);

    cout << "C++: Well...\nC++: Has anything happened?\n";

    while (true) {
        cout << "C++: Enter a string\n";
        cin >> tValue;
        cout << "C++: You have entered " << tValue << "\n";
        Tcl_UpdateLinkedVar(interp, tValue);
    }

    return 1;
}

void *thread_proc(void* x) {
    cout << "C++ TP: Thread Launched: " << "\n";

    int errEval = Tcl_EvalFile(interp,"./test.tcl");

    cout << "C++ TP: EVAL: " << errEval << "\n";

    pthread_exit(NULL);
}

和test.tcl

代码语言:javascript
复制
#!/home/gc/tcl/bin/tclsh8.6

set tValue ""

puts "I'm also alive"

after 10000

puts "about to puts"

after 1000

puts $tValue

after 10000

puts "about to end"

after 1000

puts "Ended"

任何帮助都将不胜感激,我只是在敲击键盘,试图让它工作……如果失败了..。

EN

回答 1

Stack Overflow用户

发布于 2014-10-12 03:18:36

要做到这一点,正确的方法是首先认识到Tcl在多线程应用程序方面有一个弱点,或者,我应该说是一个限制:它使用“单元线程”模型。这意味着在线程中完成的所有操作都必须与任何其他线程保持“分离”。

具体地说,创建解释器的线程是唯一可以与该解释器交互的线程。这包括所有Tcl_xxx C应用编程接口函数的使用。唯一的例外是Tcl_AsyncXXX应用编程接口函数,这一点很重要。

为了在线程间正确使用链接的变量,您不应该从独立于Tcl线程运行的基于C的线程调用Tcl_UpdateLinkedVar。相反,线程应该使用Tcl_AsyncCreate()等初始化异步事件令牌和处理程序,并使用相关函数调用Tcl线程中异步处理程序,此时处理程序可以安全地调用Tcl_UpdateLinkedVar()。由于异步处理程序将始终在创建异步事件令牌的线程中执行,您将在调用Tcl_AsyncMark()时使用该令牌,因此它将正常工作,并且将保留Tcl所需的线程模型的单元性。

我希望我有更多的时间给出一个更完整的答案,但我认为这将使您走上高效的轨道,如果您考虑:在一个线程中更新var,在C中,与Tcl解释器是“异步”的,因此您必须使用异步机制将Tcl var的更新“传递”给运行您正在使用的Tcl interp的线程。

祝好运!

PS:在我写这篇文章的时候,我正在看活动状态Tcl 8.5.15.0 for Windows帮助文档。文档非常好,而且大部分都是跨平台的;我推荐它至少是您经常使用的配套参考之一。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18898644

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档