2

I am facing crash while trying to create one tcl interpreter per thread. I am using TCL version 8.5.9 on linux rh6. It crashes in different functions each time seems some kind of memory corruption. Going through net it seems a valid approach. Has anybody faced similar issue? Does multi-threaded use of Tcl need any kind of special support?

Here is the following small program causing crash with tcl version 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);
}
Alok
  • 21
  • 2

2 Answers2

1

The default Tcl library isn't built thread enabled. (well, not with 8.5.9 afaik, 8.6 is).

So did you check that your tcl lib was built thread enabled?

If you have a tclsh built against the lib, you can simply run:

% 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

If ::tcl_platform(threaded) is 0, your build isn't thread enabled. You would need to build a version with thread support by passing --enable-threads to the configure script.

Did you use the correct defines to declare you want the thread enabled Macros from tcl.h? You should add -DTCL_THREADS to your compiler invocation, otherwise the locking macros are compiled as no-ops.

schlenk
  • 7,002
  • 1
  • 25
  • 29
  • I ran that command and it does print other option but not ::tcl_platform(threaded) one. Seems thread support is not enabled. I would try with compiling with thread support enabled. thanks for help. – Alok Oct 04 '13 at 09:18
1

You need to use a thread-enabled build of the library.

When built without thread-enabling, Tcl internally uses quite a bit of global static data in places like memory management. It's pretty pervasive. While it might be possible to eventually make things work (provided you do all the initialisation and setup within a single thread) it's going to be rather unadvisable. That things crash in strange ways in your case isn't very surprising at all.

When you use a thread-enabled build of Tcl, all that global static data is converted to either thread-specific data or to appropriate mutex-guarded global data. That then allows Tcl to be used from many threads at once. However, a particular Tcl_Interp is bound to the thread that created it (as it uses lots of thread-specific data). In your case, that will be no problem; your interpreters are happily per-thread entities.

(Well, provided you also add a call to initialise the Tcl library itself, which only needs to be done once. Put Tcl_FindExecutable(NULL); inside main() before you create any of those threads.)


Tcl 8.5 defaulted to not being thread-enabled on Unix for backward-compatibility reasons — on Windows and Mac OS X it was thread-enabled due to the different ways they handle low-level events — but this was changed in 8.6. I don't know how to get a thread-enabled build on RH6 (other than building it yourself from source, which should be straight-forward).

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • Yes, I compiled it myself on RH6 with thread enabled support. Even though it crashed, I would add call - Tcl_FindExecutable(NULL); Lets see if this makes difference. Thanks for response. – Alok Oct 04 '13 at 11:32
  • Hi Donal, Without "Tcl_FindExecutable(NULL);" in main(), application is still crashing with Tcl (compiled with --enable-threads option). On web I could not find out what Tcl_FindExecutable does to make Tcl work with multi-threaded app. Could you please give some insight/pointers if you have any idea? Thanks in advance. – Alok Oct 04 '13 at 13:28
  • @Alok does it crash if you call `Tcl_FindExecutable`? As I already said, this is the first Tcl_* function that you should call in a process. It doesn't crash if you call them more than once (afaik). Just call it. – Johannes Kuhn Oct 04 '13 at 15:37
  • @Alok: It initialises the Tcl library itself (especially the memory management, filesystem interface and charset translator). You can also pass in `main`'s `argv[0]` as a non-NULL to tell it where the executable is, but that's usually not so critical (unless your scripts depend on `info nameofexecutable`, of course). – Donal Fellows Oct 05 '13 at 14:51