Re: Threading advice sought
From: Melissa Schrumpf (m_schrumpf_at_yahoo_com_NOT_at_microsoft.com)
Date: Sun, 26 Dec 2004 12:57:48 -0500
Darren New wrote:
> Firstly, is a precompiled version of Tcl with threads enabled available?
> The ActiveState versions I've loaded are apparently not thread-enabled,
> as there's no mention of it in tcl_platform. Or am I going to have to
> figure out how to compile it?
Compiling is extremely straight-forward, even on Windows (with the msys
setup http://www.mingw.org/msys.shtml). The files in the toplevel of
the extracted tarball tell you to basically cd to to directory for your
platform, configure, make, make test, and make install. Just do
./configure --help to see what features you want to enable (in addition
Then just grab the thread extension, and compile it. It might take you
an hour to figure it all out the first time.
There might be a precompiled distro with threads enabled, but it never
seemed like that big of a deal.
> Secondly, is the Thread package on SF the latest/greatest way to get to
> threads from the Tcl level? It looks like it from the Wiki...
I believe so.
> Thirdly, part of the start-up of the program is to read and parse a
> dozen different directories and files (basically specifying the
> capabilities of supported clients, etc.) This all gets read into a
> number of variables in a namespace tree below ::setup and ::config,
> depending. Once read, it never changes. Is there an easy way to share
> this with new threads? I suppose the easiest way would be to build up a
> thread-pool, write code to turn the namespaces into a script and pass it
> to each thread in the pool, then reuse it and have lots of copies, but
> is there something better?
For passing large or complex data structures between threads? Not that
I know of. The only solutions I can think of for inter-process /
inter-thread communication either use the facilities already built in to
tcl, or are at the C level (mapping shared memory pages, or simply
defining a "global" that would be truly global to all threads), and
would require an extension. For example, you could use sockets to send
the information from one thread to another. But going through the
filesystem really isn't very different, and does give you a written
record of state, in case you need to debug.
> Finally, assuming I'm using Tcom to talk to the COM objects, and that
> each transaction creates a COM object, uses it, and then throws it away,
> I should be able to get better performance (in terms of not blocking on
> big DB operations) by doing this, yes? Only the COM objects actually
> talk to the database, so there's no DB code in the Tcl itself.
You're going to have to do the testing for your specific application to
determine what gives the best performance. There's a lot of overhead in
creating new COM objects that you might want to do away with by reusing
old objects. On the other hand, if leaving COM objects open causes
delays in the DB server (I'm not sure why it would), then you might be
correct. It all depends on the specifics of your setup.
You can think about it in terms of other servers. If you've done any
work with daemons on various unix systems, you'll see that some servers
spawn a brand new instance every time they get a connect request on a
given port; some run one instance, or a set number of instances
constantly, to service incoming connections, and use threads as needed
to subdivide work.
So, I guess my suggestion here is to start with your performance
parameters: start with a system load profile that adequately reflects
your worst-case scenarios, mock up some prototype variations, and see
what performs best.
Basically, I see two options: create new COM objects for every request,
or create a pool of COM objects for reuse. For the latter, you could
define performance tuning parameters to tweak, such as how many objects
should be in the pool (to balance how quickly your transactions
complete, versus how quickly your requests arrive). Additionally, you
could set load or latency levels for when to create and recycle
additional COM objects, and the maximum size you'd allow the pool to
grow to. This is a more complex implementation, but based on (limited)
my experience with COM, very well may run faster if you don't have to
create new COM objects constantly.