Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Thread extension and separated interpreters

83 views
Skip to first unread message

Googie

unread,
Nov 3, 2009, 3:00:35 PM11/3/09
to
Hi,

Why thread extension uses new interpreter for each created thread?
I know that it might be useful in some cases, but wouldn't it be nice
to have choice between current and new interpreter while creating a
thread?

Is it matter of implementation, that makes it pretty hard to do that?

David Gravereaux

unread,
Nov 3, 2009, 3:42:12 PM11/3/09
to


Sorry, not possible. An interp is an executional state. You want more,
sure! You want some to run in different threads, sure. You want
multiple threads to access the same state, no way!

Tcl uses the apartment model so as not to become a slow dog, thus
require the use of threads to get any decent performance from it in the
single thread case working against a global interpreter lock. And the
easy part goes away. For example, any extension that associates it's
internal state with the interp in use is by definition, thread safe.
Now wasn't that easy?

IMO, the *best* use of threads is for routines that block for long
periods... FFT audio processing, gethostbyname, SQL queries, etc.
During those blocks it would be really awful to have an unresponsive Tk
GUI. You don't need simultaneous access to a single interp to allow
that. Spawn off a new one or grab a free one from a pool, ask it to do
the work and send an event back when accomplished. Easy peasy.

Once you make good use of the event loop, tagging on a little threading
for the troubled spots is quite easy.

^-- IMO, of course.

--


signature.asc

Don Porter

unread,
Nov 3, 2009, 4:56:47 PM11/3/09
to

http://www.tcl.tk/doc/howto/thread_model.html

--
| Don Porter Mathematical and Computational Sciences Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|

Donal K. Fellows

unread,
Nov 3, 2009, 7:23:33 PM11/3/09
to
On 3 Nov, 20:42, David Gravereaux <davyg...@pobox.com> wrote:
> IMO, the *best* use of threads is for routines that block for long
> periods...

Spoken like someone used to single-processor machines. :-) In fact,
the best use of threads is to enable full utilization of multi-core
systems, which are far more common than they used to be. Dealing with
blocking calls (or other IO-bound behavior) is just a side-benefit of
the heart (being able to handle CPU-bound MIMD multiprogramming).

The great thing about Tcl's thread support is that it is far more lock-
free than most languages' threading is. This means that when you do
run on two cores or more, Tcl will get a much larger fraction of the
potential speedup than others (indeed, at least in the past it was
well-known - with evidence - that Python's behavior was pathological
in the presence of multiple cores). It does this by partitioning the
space of resources[*] and giving each thread its own pool; only when
that thread-local pool is exhausted does the global master allocator
(which has to be protected with a lock) need to be invoked. There are
other benefits too, notably that because Tcl uses message-passing to
communicate between threads, it's much more theoretically tractable;
by comparison, shared-memory parallelism is scary stuff that it's easy
to really make bad mistakes with.

Donal.
[* Memory is the key resource here. Tcl uses and reuses memory a lot,
which would make a global lock in this area utterly crippling. ]

David Gravereaux

unread,
Nov 3, 2009, 10:17:23 PM11/3/09
to
Donal K. Fellows wrote:
> On 3 Nov, 20:42, David Gravereaux <davyg...@pobox.com> wrote:
>> IMO, the *best* use of threads is for routines that block for long
>> periods...
>
> Spoken like someone used to single-processor machines. :-) In fact,
> the best use of threads is to enable full utilization of multi-core
> systems, which are far more common than they used to be. Dealing with
> blocking calls (or other IO-bound behavior) is just a side-benefit of
> the heart (being able to handle CPU-bound MIMD multiprogramming).

Don't know about you, but the most issues I've bumped into all has to do
with better use of I/O to keep a fluffy event loop. A certain robotic
project of my past comes to mind. Even when you are blessed with the
ability to parallelize an algo (many arms and joints moving at once, in
my case with four galil motion controllers and three serial ports),
there sits a top to it that has to manage the overall process in a
serialized manner.

When is affinity coming to the thread extension?

To be quite honest, when performance becomes important you do the number
crunching in C instead of script and probably use the OS provided
threading there directly and just give it an extension interface which
might probably be controlled from a single thread. That's where I'd go
first as life is better when kept simple. We're Tool Command Language,
not tool-less language.

Ever tried to do FFT in script? I chose the 50x speed-up in C that had
a good sprinkle of SSE2 instructions, myself.
--


signature.asc

Googie

unread,
Nov 4, 2009, 2:26:57 AM11/4/09
to
Don Porter wrote:

> http://www.tcl.tk/doc/howto/thread_model.html

That's clear, thanks.
But...

How should I (we?) deal with extensions like itcl or sqlite?

About itcl - my only idea for now is to create "clone" proc or something
like that, but it would slow down script a lot.

About sqlite - I have completly no idea how to deal with transferind
database handle object into other thread. I know I can open new handle in
other thread, but it's not same as transfering current handle.

Of course all issues can be worked around, but I don't think workarounds are
best solution...

...and yes, I saw itcl patch to use threads, but its very old and I don't
think it applies for itcl4.0, or even 3.4.

--
Pozdrawiam! (Regards!)
Googie

Mark Janssen

unread,
Nov 4, 2009, 6:39:29 AM11/4/09
to

What does Itcl have to do with threads? You mean using a class from
one thread in another? That is basically what the compartimentalized
thread model prevents and this is a good thing IMO. With regards to
SQLite, you'll just open the same DB in the second thread and let
SQLite worry about concurrency.

HTH,
Mark

Googie

unread,
Nov 4, 2009, 1:14:38 PM11/4/09
to
Mark Janssen wrote:

> What does Itcl have to do with threads? You mean using a class from
> one thread in another? That is basically what the compartimentalized
> thread model prevents and this is a good thing IMO.

Letting developer to choose is better IMO.
But this is piece of cake. I can always load class definition in the
other thread. Problem is transfering itcl objects, just like tsv::*
does for variables.

> With regards to
> SQLite, you'll just open the same DB in the second thread and let
> SQLite worry about concurrency.

This is workaround I meant before.


Going by this direction one would say that tsv::* or thread::transfer
is useless - you can always reach same variable values or channels by
repeating code execution in other threads.

Mark Janssen

unread,
Nov 4, 2009, 1:29:35 PM11/4/09
to
On Nov 4, 7:14 pm, Googie <pawelsal...@gmail.com> wrote:
> Mark Janssen wrote:
> > What does Itcl have to do with threads? You mean using a class from
> > one thread in another? That is basically what the compartimentalized
> > thread model prevents and this is a good thing IMO.
>
> Letting developer to choose is better IMO.
> But this is piece of cake. I can always load class definition in the
> other thread. Problem is transfering itcl objects, just like tsv::*
> does for variables.
>

1) You don't want to transfer Itcl objects between threads.
2) If you do, see 1

Having the same classes available is (as you already observed) just a
[source] or [package require] away.

> > With regards to
> > SQLite, you'll just open the same DB in the second thread and let
> > SQLite worry about concurrency.
>
> This is workaround I meant before.
>

This is not a workaround. SQLite is designed to allow concurrent
access, so use that functionality then.

> Going by this direction one would say that tsv::* or thread::transfer
> is useless - you can always reach same variable values or channels by
> repeating code execution in other threads.

Saying they are useless is a bit too much, but I do think shared
thread variables should be used very sparingly. They tend to lead to
bugs which are timing dependent and hence difficult to debug. The
message passing paradigm is much easier to reason about.

Googie

unread,
Nov 4, 2009, 3:01:30 PM11/4/09
to
Mark Janssen wrote:

> 1) You don't want to transfer Itcl objects between threads.
> 2) If you do, see 1

What kind of argument is that?

> Having the same classes available is (as you already observed) just a
> [source] or [package require] away.

I do want to transfer objects between threads.

I have quiet big hierarchy of existing objects that I need to process
(which takes long time) in separated thread. A path to get this
hierarchy of objects is complex, so I won't reproduce it from scratch
in the other thread.

What would you suggest for this case?

> This is not a workaround. SQLite is designed to allow concurrent
> access, so use that functionality then.

What if we want (for some reason) to share transaction between
threads?

> Saying they are useless is a bit too much, but I do think shared
> thread variables should be used very sparingly. They tend to lead to
> bugs which are timing dependent and hence difficult to debug. The
> message passing paradigm is much easier to reason about.

Maybe it's just a matter of different models of concurrent development
that we're used to.

Donald Arseneau

unread,
Nov 4, 2009, 5:45:06 PM11/4/09
to
On Nov 4, 12:01 pm, Googie <pawelsal...@gmail.com> wrote:
> Mark Janssen wrote:
> > 1) You don't want to transfer Itcl objects between threads.
> > 2) If you do, see 1
>
> What kind of argument is that?

Oh I'm sorry, this is abuse. Arguments are just down the corridor.

Oh I'm sorry, this is Tcl. Python is just down the page.

Donald Arseneau

David Gravereaux

unread,
Nov 4, 2009, 7:23:42 PM11/4/09
to
Donald Arseneau wrote:

> Oh I'm sorry, this is abuse. Arguments are just down the corridor.
>
> Oh I'm sorry, this is Tcl. Python is just down the page.
>
> Donald Arseneau

Haha. Nice Monty Python reference. Even more funny as Python the
scripting language uses the global lock convention.
--

Donal K. Fellows

unread,
Nov 5, 2009, 4:33:17 AM11/5/09
to
On 4 Nov, 20:01, Googie <pawelsal...@gmail.com> wrote:
> Mark Janssen wrote:
> > This is not a workaround. SQLite is designed to allow concurrent
> > access, so use that functionality then.
>
> What if we want (for some reason) to share transaction between
> threads?

That's not supported. Keep the transaction in a single thread and feed
outputs from the other (worker?) threads back through the transaction
holder.

Donal.

Googie

unread,
Nov 5, 2009, 6:52:22 AM11/5/09
to
Donal K. Fellows wrote:

>> What if we want (for some reason) to share transaction between
>> threads?
>
> That's not supported. Keep the transaction in a single thread and feed
> outputs from the other (worker?) threads back through the transaction
> holder.

Ok, sqlite wasn't best example. Nevertheless Itcl objects are.

--
Pozdrawiam! (Regards!)
Googie

Mark Janssen

unread,
Nov 5, 2009, 7:53:44 AM11/5/09
to
On Nov 4, 9:01 pm, Googie <pawelsal...@gmail.com> wrote:
> Mark Janssen wrote:
> > 1) You don't want to transfer Itcl objects between threads.
> > 2) If you do, see 1
>
> What kind of argument is that?

It's a silly way to say, if you need to pass Itcl objects between
threads, you should rethink your solution strategy instead.

>
> > Having the same classes available is (as you already observed) just a
> > [source] or [package require] away.
>
> I do want to transfer objects between threads.
>
> I have quiet big hierarchy of existing objects that I need to process
> (which takes long time) in separated thread. A path to get this
> hierarchy of objects is complex, so I won't reproduce it from scratch
> in the other thread.
>
> What would you suggest for this case?
>

One option would be to only build this big hierarchy of objects in the
calculating thread and let the 'master' thread only kick off the
calculation. Another option would be to serialize the calculation from
the hierachy of objects. In general I do think it makes sense to make
the actual calculations as independend from the representation of the
input as possible. In this case you could fire off the seperate
calculation steps from the master thread. Without more info of the
actual calculation and object hierarchy, I can't give any more advice.

> > This is not a workaround. SQLite is designed to allow concurrent
> > access, so use that functionality then.
>
> What if we want (for some reason) to share transaction between
> threads?
>
> > Saying they are useless is a bit too much, but I do think shared
> > thread variables should be used very sparingly. They tend to lead to
> > bugs which are timing dependent and hence difficult to debug. The
> > message passing paradigm is much easier to reason about.
>
> Maybe it's just a matter of different models of concurrent development
> that we're used to.

Maybe, but do note that Tcl's thread model is better suited for
message passing concurrency style than memory sharing concurrency. And
it often makes sense to use a paradigm that fits your environment.

Mark

Neil Madden

unread,
Nov 5, 2009, 8:20:29 AM11/5/09
to
Googie wrote:
> Mark Janssen wrote:
>
>> 1) You don't want to transfer Itcl objects between threads.
>> 2) If you do, see 1
>
> What kind of argument is that?
>
>> Having the same classes available is (as you already observed) just a
>> [source] or [package require] away.
>
> I do want to transfer objects between threads.
>
> I have quiet big hierarchy of existing objects that I need to process
> (which takes long time) in separated thread. A path to get this
> hierarchy of objects is complex, so I won't reproduce it from scratch
> in the other thread.

Can you completely encapsulate all of these objects in the separate
thread? I.e., you have a "model" thread that handles all of these
objects, and a "view" thread that displays details from them. The view
thread sends request messages to the model thread when it needs
particular details.

>
> What would you suggest for this case?
>
>> This is not a workaround. SQLite is designed to allow concurrent
>> access, so use that functionality then.
>
> What if we want (for some reason) to share transaction between
> threads?

You shouldn't ever be doing this in any language. If you really want
multiple threads interacting with the same transaction then you should
nominate a thread to "own" the transaction, and other threads send their
data to this thread for update. Generally though, DB transactions are
designed to be used on a per-thread basis.

>
>> Saying they are useless is a bit too much, but I do think shared
>> thread variables should be used very sparingly. They tend to lead to
>> bugs which are timing dependent and hence difficult to debug. The
>> message passing paradigm is much easier to reason about.
>
> Maybe it's just a matter of different models of concurrent development
> that we're used to.

If you can make the Tcl model work for you, it's likely to be
considerably easier to maintain and debug than the alternatives.

-- Neil

Donal K. Fellows

unread,
Nov 5, 2009, 10:27:14 AM11/5/09
to
On 5 Nov, 11:52, Googie <n...@spam.0rg> wrote:
> Ok, sqlite wasn't best example. Nevertheless Itcl objects are.

Itcl objects can't be shared, but you could create a proxy object in
one thread that invokes operations on the real object within the other
thread. However, I'm not at all sure whether that's a good model for
what you seek to do (it sounds like you're still trying to do the
shared memory model, which Tcl rejects).

Donal.

Gerald W. Lester

unread,
Nov 5, 2009, 12:38:30 PM11/5/09
to
Googie wrote:
> Mark Janssen wrote:
>...

>> Saying they are useless is a bit too much, but I do think shared
>> thread variables should be used very sparingly. They tend to lead to
>> bugs which are timing dependent and hence difficult to debug. The
>> message passing paradigm is much easier to reason about.
>
> Maybe it's just a matter of different models of concurrent development
> that we're used to.

Yes, I'm sure that is the problem.

Tcl's model is the apartment model. Threads communicate by message passing
-- not shared memory/code.

Just like a lot of other paradigms in Tcl vs language X -- you need to
adjust your thinking/design to use the Tcl paradigm(s) not the one(s) used
in another language.


--
+------------------------------------------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+

Andreas Otto

unread,
Nov 13, 2009, 8:23:14 AM11/13/09
to
Hi,

I understand your problem but thread and tcl is a problem .....

-> as already mentioned one interpreter per thread is the limitation
-> new thread -> new interpreter

-> solution: disable thread extension and use fork:

reason:

1. performance:

data from: http://libmsgque.sourceforge.net/performance.htm

create a new tcl instance (bigger is bad)

thread -> ~8413
fork -> ~860

-> 10 times faster

the goal is with a "fork" you can reuse the already available
interpreter

2. communication between PARENT main interpreter and
SLAVE thread interpreter

I have written a TCL extension:
http://libmsgque.sourceforge.net/performance.htm
for this task ....
the following command solves your problem
http://libmsgque.sourceforge.net/tclmsgque/group__tclmsgque.htm#tcl_slave


mfg

Andreas Otto (aotto1968)

Uwe Klein

unread,
Nov 13, 2009, 8:51:07 AM11/13/09
to
Andreas Otto wrote:
> 1. performance:
>
> data from: http://libmsgque.sourceforge.net/performance.htm
>
> create a new tcl instance (bigger is bad)
>
> thread -> ~8413
> fork -> ~860

that is on Linux, right?
linux used to be the strange child in that respect ( i.e. a fork being "cheap" )

How does it compare to other unixy platforms and very important : windows.

uwe

Andreas Otto

unread,
Nov 13, 2009, 9:31:17 AM11/13/09
to
Yes, you are right it's linux ...
and your are right too windows has no fork ->
you have to spawn a new process (or a thread) and
you get a new interpreter -> no speed improvement
other UNIX like OS have the gain because if a
fork is available the interpreter can be reused
-> boost on performance

more details now:

data from http://localhost/msgque/performance.htm

C Tcl JAVA
uds_fork 294 860 n·a.
uds_thread 140 8413 323

the following information is important:

C) it is faster to create a "thread" as to create a new
"fork"
Tcl) it is faster to create a "fork" as to create a new
"thread" -> why?

a tcl has "thread" always the overhead to create *AND* initialize the
interpreter too -> if thread creating is "slower" than fork
a process the thread is useless (at least on UNIX/LINUX)

java has only one JVM -> the language benefit from the
"thread" creation performance


mfg

Andreas Otto (aotto1968)

0 new messages