我在尝试为每个线程创建一个tcl解释器时遇到崩溃。我在Linux rh6上使用TCL版本8.5.9。它每次都会在某些内存损坏时崩溃。通过网络似乎是一种有效的方法。有人遇到过类似的问题吗?多线程使用Tcl是否需要任何特殊支持?
以下是使用tcl版本8.5.9导致崩溃的以下小程序。
#include <tcl.h>
#include <pthread.h>
void* run (void*)
{
Tcl_Interp *interp = Tcl_CreateInterp();
sleep(1);
Tcl_DeleteInterp(interp);
}
main ()
{
pthread_t t1, t2;
pthread_create(&t1, NULL, run, NULL);
pthread_create(&t2, NULL, run, NULL);
pthread_join (t1, NULL);
pthread_join (t2, NULL);
}
答案 0 :(得分:1)
默认的Tcl库未启用构建线程。 (好吧,不是8.5.9 afaik,8.6是)。
所以你检查你的tcl lib是否已经构建了线程?
如果您针对lib构建了tclsh
,则只需运行:
% parray ::tcl_platform
::tcl_platform(byteOrder) = littleEndian
::tcl_platform(machine) = intel
::tcl_platform(os) = Windows NT
::tcl_platform(osVersion) = 6.2
::tcl_platform(pathSeparator) = ;
::tcl_platform(platform) = windows
::tcl_platform(pointerSize) = 4
::tcl_platform(threaded) = 1
::tcl_platform(wordSize) = 4
如果::tcl_platform(threaded)
为0,则表示您的构建未启用线程。您需要通过将--enable-threads
传递给configure脚本来构建具有线程支持的版本。
您是否使用正确的定义来声明您希望从tcl.h启用线程的宏?
您应该将-DTCL_THREADS
添加到编译器调用中,否则锁定宏将编译为no-ops。
答案 1 :(得分:1)
您需要使用基于线程的库构建。
在没有线程启用的情况下构建时,Tcl内部在内存管理等地方使用了相当多的全局静态数据。它非常普遍。虽然最终可能会使事情有效(如果你在一个线程中进行所有初始化和设置),那将是相当不可取的。在你的情况下,事情以奇怪的方式崩溃并不是很令人惊讶。
当您使用启用线程的Tcl版本时,所有全局静态数据都将转换为特定于线程的数据或转换为适当的互斥锁全局数据。然后允许一次从多个线程使用Tcl。但是,特定的Tcl_Interp
绑定到创建它的线程(因为它使用了大量特定于线程的数据)。在你的情况下,这将没有问题;你的口译员很满意每个线程的实体。
(好吧,如果您还添加了一个初始化Tcl库本身的调用,只需要执行一次。在创建任何这些线程之前将Tcl_FindExecutable(NULL);
置于main()
内。)