Reusing Threads

G

Guest

I have an application with a C# menu, that calls individual C programs, by
starting a thread for each call. This way the program is in one thread, and
the menu is in another thread, until they exit the program and that thread
ends.

The problem is the static data in the program, such as database buffers. If
the data is regular static data, then the database connection is retained
between calls to the program, which is good. But if the user initiates a
second menu option while the first one is running, the data is shared between
them, which is bad.

The solution to that is to make the data Thread static, like this:

#define Thread __declspec(thread)
Thread static char MyPublicData[100]="My Public Data";

This makes the data unique to each time the C program runs, so that the
database connections do not get corrupted. The problem is that it if the user
calls an option, exits, and calls another one, the data should be retained,
like regular static data. But if they call one, then call another while the
first one is still running, it should be a new set of static data, like
Thread static.

My thought was to use a thread for a program, then reuse the same thread
again for the second call that came after the first one ended. If the user
ran two at once, I would initialize a second thread. But when I try and reuse
a thread, I get an error, that the thread is dead. I reused it simply by
running

RThread.Start();

A second time, where

Thread RThread = new Thread();

So my question is, is there a way to reuse the thread after it has ended, so
that I can preserve the data from call to call sometimes, but not at other
times? Thanks for any suggestions.
 
P

Peter Duniho

[...]
So my question is, is there a way to reuse the thread after it has ended, so
that I can preserve the data from call to call sometimes, but not at other
times? Thanks for any suggestions.

Yes and no. There is no way to reuse a thread after it's actually
exited. However, you certainly could create your own thread pool
implementation that works similarly to the existing thread pool in
..NET. You'd want to implement your own, because you'll want enough
control to make sure that the same thread you've already used once is
used again as long as it's not busy.

The basic idea is not hard: start one or more threads, all of which sit
idle until code in some other thread (usually your main thread) adds a
delegate to an execution queue and signals that there is a new element
in the queue. You'd wake up the threads, they'd look in the queue for
the delegate, and execute any delegate they find. Access to the queue
would be synchronized, of course, so that any given element in the
queue is retrieved by only one thread.

The threads never actually exit in this design; they just sit in a loop
looking for delegates to execute. So per-thread data is preserved
between executions.

Note that using a delegate is just one way to implement this (the most
general-purpose way, IMHO). If you have some sort of parameter- or
command-based execution model, you could implement that in the thread
code, and queue the parameters/commands instead of an actual delegate.

Now, all that said, I'm not convinced that your goal is necessarily a
good one. I understand the desire to cache data for reuse. But if you
have a situation where the data may be reused sometimes and not others,
it creates potential ambiguities. For example, when you have more than
one thread executing at a time, which thread's data do you want
preserved for a subsequent execution? Do you want it to be the thread
that first started executing? First finished executing? Last finished
executing? Some other criteria? How do you expect to enforce that?

You haven't posted enough details about the specific relationships
between the various threads, but the fact that you ran into a problem
at all suggests that your design as-is may be somewhat fragile and will
lead to other bugs in the future, even if you successfully address the
immediate problem. It may be better to step back and think about the
higher-level goals and a better way to address those.

Pete
 
G

Guest

Thanks Pete, I think that is what I need, a thread pool that I can manage
myself. I will need to figure out how to monitor for delegates and wake the
threads up, but now I know where to start.


Peter Duniho said:
[...]
So my question is, is there a way to reuse the thread after it has ended, so
that I can preserve the data from call to call sometimes, but not at other
times? Thanks for any suggestions.

Yes and no. There is no way to reuse a thread after it's actually
exited. However, you certainly could create your own thread pool
implementation that works similarly to the existing thread pool in
..NET. You'd want to implement your own, because you'll want enough
control to make sure that the same thread you've already used once is
used again as long as it's not busy.

The basic idea is not hard: start one or more threads, all of which sit
idle until code in some other thread (usually your main thread) adds a
delegate to an execution queue and signals that there is a new element
in the queue. You'd wake up the threads, they'd look in the queue for
the delegate, and execute any delegate they find. Access to the queue
would be synchronized, of course, so that any given element in the
queue is retrieved by only one thread.

The threads never actually exit in this design; they just sit in a loop
looking for delegates to execute. So per-thread data is preserved
between executions.

Note that using a delegate is just one way to implement this (the most
general-purpose way, IMHO). If you have some sort of parameter- or
command-based execution model, you could implement that in the thread
code, and queue the parameters/commands instead of an actual delegate.

Now, all that said, I'm not convinced that your goal is necessarily a
good one. I understand the desire to cache data for reuse. But if you
have a situation where the data may be reused sometimes and not others,
it creates potential ambiguities. For example, when you have more than
one thread executing at a time, which thread's data do you want
preserved for a subsequent execution? Do you want it to be the thread
that first started executing? First finished executing? Last finished
executing? Some other criteria? How do you expect to enforce that?

You haven't posted enough details about the specific relationships
between the various threads, but the fact that you ran into a problem
at all suggests that your design as-is may be somewhat fragile and will
lead to other bugs in the future, even if you successfully address the
immediate problem. It may be better to step back and think about the
higher-level goals and a better way to address those.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top