473,903 Members | 4,560 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

threading - suspend, resume, abort

I have an application which consists of a main work thread and
multiple threads which each maintain a TCP socket.

When a configuration change occurs, all activity on the socket threads
must be halted. If a socket is no longer in the configuration, that
thread must be aborted and the socket must be closed. After the
configuration is complete, the remaining threads must be resumed.

I currently have the following architecture:

1) Suspend all threads
2) Abort threads which are no longer required and close their sockets
3) Resume all remaining threads.

If I suspend a thread and then abort it, CPU usage jumps to 100%. I
must first resume the thread and then abort it. This doesn't seem
right, so I'm wondering if I'm missing something here.

I also found in MSDN that Microsoft does not recommend using these
methods. If that's the case, then what is the proper technique?

thanks,
Keith
Jul 21 '05 #1
11 2790
I would do it very differently:

Instead of interrupting all the threads and aborting some of them brutally
when the config changes, I would do the following:

Every thread must have some kind of loop like
while (ReadRequest()) {
DispatchRequest ();
WriteResponse() ;
}
(this is pseudo-code of course).

In the ReadRequest, I would interrogate the configuration manager, with a
call like configManager.I sAllowed(connec tionInfo), and terminate the loop if
the method returns false.

If the configuration changes, I would call a method like
configManager.C hangeConfig(con figInfo).

Then, you only have to solve two problems:

* Make sure that your configuration manager is correctly synchronized. The
methods IsAllowed and ChangeConfig should be synchronized on a common lock
so that a thread cannot call IsAllowed while another thread is in the middle
of executing ChangeConfig.

* Use asynchronous rather than synchronous read in ReadRequest, so that you
can terminate the threads that are not allowed any more but are blocked
waiting for input. The idea is to call StartRead and then "Wait" on the
ASyncWaitHandle of the IAsyncResult. In your config manager, you should set
a flag in all the connections that need to be terminated and signal their
ASyncWaitHandle . This will allow you to terminate these thread without
having to wait for them to receive more input.

With this strategy, you don't need to use any of the thread control method
(Abort, Suspend, Resume), you only use synchronization primitives (lock,
wait). This is much cleaner and more efficient.

Also, you should avoid "Suspend" as much as possible, except if you are
going to resume the thread or abort it immediately afterwards. If you
Suspend a thread and don't resume it or abort it immediately afterwards, you
block its execution at an unknown point, and you may very well block it in a
piece of code where it has acquired some locks. This may prevent other
threads (that are not suspended) to acquire these locks, and you run the
risk of getting a general deadlock (at least until the thread is resumed).
So, be very careful with "Suspend" because it interferes in dangerous ways
with the lock/wait synchronization pattern.

Bruno.

"Keith Langer" <ta******@aol.c om> a écrit dans le message de
news:15******** *************** ***@posting.goo gle.com...
I have an application which consists of a main work thread and
multiple threads which each maintain a TCP socket.

When a configuration change occurs, all activity on the socket threads
must be halted. If a socket is no longer in the configuration, that
thread must be aborted and the socket must be closed. After the
configuration is complete, the remaining threads must be resumed.

I currently have the following architecture:

1) Suspend all threads
2) Abort threads which are no longer required and close their sockets
3) Resume all remaining threads.

If I suspend a thread and then abort it, CPU usage jumps to 100%. I
must first resume the thread and then abort it. This doesn't seem
right, so I'm wondering if I'm missing something here.

I also found in MSDN that Microsoft does not recommend using these
methods. If that's the case, then what is the proper technique?

thanks,
Keith

Jul 21 '05 #2
Keith Langer <ta******@aol.c om> wrote:
I have an application which consists of a main work thread and
multiple threads which each maintain a TCP socket.

When a configuration change occurs, all activity on the socket threads
must be halted. If a socket is no longer in the configuration, that
thread must be aborted and the socket must be closed. After the
configuration is complete, the remaining threads must be resumed.

I currently have the following architecture:

1) Suspend all threads
2) Abort threads which are no longer required and close their sockets
3) Resume all remaining threads.

If I suspend a thread and then abort it, CPU usage jumps to 100%. I
must first resume the thread and then abort it. This doesn't seem
right, so I'm wondering if I'm missing something here.

I also found in MSDN that Microsoft does not recommend using these
methods. If that's the case, then what is the proper technique?


Each socket's work thread should regularly check whether or not it
needs to pause/restart/shutdown. Usually this is just a case of
changing the condition of an otherwise endless loop.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #3
Thanks guys. I took the approach of setting a flag from the main thread
which directs the socket thread to abort or suspend. Now the socket
thread handles these actions when it is safe to do so.

According to MSDN, the Abort method only executes when it is safe, so
I'm guessing that at the very least it waits until all locks are
released. Is this not the case? After testing it, I found that the
abort did take a few seconds.

One more question - if the main thread can read or write to a hashtable
and the socket thread reads from that hashtable, is there any danger of
an incomplete write operation while the socket thread is accessing an
item by its key? I am not using enumeration.

thanks,
Keith

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Jul 21 '05 #4
If you have a flag, why do you still need to call abort or suspend?

My assumption was that you would set the flag on the threads that need to be
aborted, and only on these threads.

Then, the threads that don't have the flag set should continue running, they
don't need to be suspended.

And the threads that have the flag set should terminate by testing the flag.
You should test the flag in your loops (my assumption was that you only had
one main loop in every thread but you code may be a bit more complex) and
the thread will terminate. The only difficulty here is terminating threads
that may be waiting for input and thus won't test the flag until they
receive new input. My suggestion to use asynch read was a way to handle this
case.

Calling abort will not wait for locks to be released (may never happen), but
it will release all the locks by propagating a special exception. So, you
are ok here.

It seems to me that you are using a strange strategy to handle concurrent
access on a shared resource (your config data). Instead of protecting the
shared resource with monitors (using the C# lock keyword to synchronize the
methods that access the config data), you are interrupting all threads when
you need to modify the shared data, and you are resuming them after the
shared data has been modified. Your approach has several **major** problems:

* Performance: stopping and resuming all threads costs a lot more than
acquiring a monitor. Also, you interrupt everything everytime you need to
modify the shared data. If you used the monitor strategy instead, the other
threads will be able to continue while the config is being modified, at
least as long as they don't try to read the config (they they will block on
the monitor until the modification is complete).

* Correctness of your logic and risks of deadlock. The threads will get
suspended and resumed at random points in their execution. If the config is
stored in a hash table and if the threads use hash table lookup logic to
retrieve it, you run the risk of interrupting a thread in the middle of the
lookup operation. For example, the thread may have computed the bucket index
but may not have obtained the bucket itself. If the main thread interrupts
at this specific point and triggers a rehash of the table, the thread that
does the lookup will do unpredictable things when it gets resumed (because
the hash table will contain a different bucket at the index that was
computed before the interruption).
And, things are even worse if you synchronize the hash table. In this case,
the thread that does the lookup will acquire the monitor on the hash table
to do the lookup. Then the main thread will suspend it in the middle of the
lookup. And then the main thread will try to modify the hash table and will
block forever because the table's monitor is acquired by a thread that is
suspended (suspending a thread does not release the monitors that it owns).
Your server will be dead!

So, the answer to your last question is: Yes, you will be in serious trouble
if you use this strategy and if you share a hashtable between your main
thread and the socket thread.

So, I strongly encourage your to avoid suspend and abort and to code
everything with monitors.

Bruno

"Keith Langer" <ta******@aol.c om> a écrit dans le message de
news:O5******** ******@TK2MSFTN GP10.phx.gbl...
Thanks guys. I took the approach of setting a flag from the main thread
which directs the socket thread to abort or suspend. Now the socket
thread handles these actions when it is safe to do so.

According to MSDN, the Abort method only executes when it is safe, so
I'm guessing that at the very least it waits until all locks are
released. Is this not the case? After testing it, I found that the
abort did take a few seconds.

One more question - if the main thread can read or write to a hashtable
and the socket thread reads from that hashtable, is there any danger of
an incomplete write operation while the socket thread is accessing an
item by its key? I am not using enumeration.

thanks,
Keith

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!

Jul 21 '05 #5
> According to MSDN, the Abort method only executes when it is safe, so
I'm guessing that at the very least it waits until all locks are
released. Is this not the case? After testing it, I found that the
abort did take a few seconds.

No, that is not correct. The link below is to the Abort documentation, where
it makes it clear that this is not the case. You may be experiencing a delay
because the thread you are aborting may actually be executing unmanaged
code, and the abort exception will not be raised until after the thread
returns to managed code.

http://msdn.microsoft.com/library/de...borttopic2.asp

As Bruno pointed out, using Suspend/Resume is not the way you should be
doing this.

Jul 21 '05 #6
The flag is something I just added so that instead of the main thread
aborting the socket thread, the socket thread aborts itself. You are
right that there is one loop (wouldn't an async call create another
thread?). There is essentially a main loop and an inner "retry" loop,
and in both places I check for the abort flag and throw an exception if
it's true. The main loop handles this exception by closing the socket
and aborting it's own thread. On the outer loop, I check for the
"suspend" flag, but it might not even be necessary to suspend
activities.

As far as config operations interfering with the socket operations, this
does not happen regularly. There are two types of changes which could
affect the socket thread -

1) A change to the socket address or port, which causes the existing
thread to be aborted and a new one to be created.

2) The addition, modificaton, or deletion of a device on the socket. In
this case, the only risk is that the socket thread is processing a
message for a device that has just been deleted. Each message contains
a key which references the source device. Before sending each message,
a reference to the device is obtained (via a hashtable lookup) so that
it can validate the response through the device object. If the device
does not exist (because the main thread removed it from the hashtable),
an exception is thrown and the messages for that device are not sent.

Obtaining the reference to the device is the main operation that could
be stepped on by the configuration thread (if the device is deleted).
I've thought about using a queue to passively inform the socket thread
of device additions and deletions, but I'm wondering if this is
overkill. I think there is still risk with this approach, since I
either have to pass a reference to the device through the queue, or I
would have to pass a key and then access the device from a global
collection (which could also be modified by the main thread).

Any thoughts?
Keith

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Jul 21 '05 #7

Bruno,

I removed the suspend flag (but kept the abort flag) and added locks to
the hashtable when the socket thread reads from it or when the main
thread removes from it. Does this approach sound better?

Keith

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Jul 21 '05 #8

Bruno,

One more question - is there much additional overhead to a synclock if
two threads never actually lock the object at the same time?

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Jul 21 '05 #9
Hi Keith,

See my comments inline...

"Keith Langer" <ta******@aol.c om> a écrit dans le message de
news:OI******** ******@TK2MSFTN GP12.phx.gbl...
The flag is something I just added so that instead of the main thread
aborting the socket thread, the socket thread aborts itself. You are
right that there is one loop (wouldn't an async call create another
thread?). There is essentially a main loop and an inner "retry" loop,
and in both places I check for the abort flag and throw an exception if
it's true. The main loop handles this exception by closing the socket
and aborting it's own thread. On the outer loop, I check for the
"suspend" flag, but it might not even be necessary to suspend
activities.
Sounds good.

As far as config operations interfering with the socket operations, this
does not happen regularly. There are two types of changes which could
affect the socket thread -

1) A change to the socket address or port, which causes the existing
thread to be aborted and a new one to be created.

2) The addition, modificaton, or deletion of a device on the socket. In
this case, the only risk is that the socket thread is processing a
message for a device that has just been deleted. Each message contains
a key which references the source device. Before sending each message,
a reference to the device is obtained (via a hashtable lookup) so that
it can validate the response through the device object. If the device
does not exist (because the main thread removed it from the hashtable),
an exception is thrown and the messages for that device are not sent.

Obtaining the reference to the device is the main operation that could
be stepped on by the configuration thread (if the device is deleted).
I've thought about using a queue to passively inform the socket thread
of device additions and deletions, but I'm wondering if this is
overkill. I think there is still risk with this approach, since I
either have to pass a reference to the device through the queue, or I
would have to pass a key and then access the device from a global
collection (which could also be modified by the main thread).
Sounds good too. I would go for the simple hashtable solution.
The queue just makes things more complex.

Whether you use a central hashtable lookup or a queue, you need
synchronization because
you will have more than one thread accessing a common data structure.

Any thoughts?
A bit more in response to your other replies...
Keith

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!

Jul 21 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
3559
by: Carlos Kirkconnell | last post by:
I'm programming a multi - threaded application using C#. I have two questions regarding to the use of threads 1- I have a Hashtable that will have multiple writters and multiple readers. I used the synchronized method to get a synchronized Hashtable. The documentation says that enumerating is not a thread safe operation; even using a synchronized Hashtable. The Hashtable has a "ContainsKey" method, is this method thread safe? Does the...
7
1605
by: SharpCoderMP | last post by:
hi, i have a problem: i wrote a class that encapsulates communication with database. i wont go into details, but i wanted to use threads to avoid unresponsive ui so i did something more or less like this: public void ExecuteScalar(string query) { this.query = query; this.workingThread.Resume(); //the worker thread is suspended
11
459
by: Keith Langer | last post by:
I have an application which consists of a main work thread and multiple threads which each maintain a TCP socket. When a configuration change occurs, all activity on the socket threads must be halted. If a socket is no longer in the configuration, that thread must be aborted and the socket must be closed. After the configuration is complete, the remaining threads must be resumed. I currently have the following architecture:
1
1072
by: john | last post by:
Waqas when i am using Thread.abort() and Thread.suspend(). the background process is not stopped. it runs continiously. i have checked the thread state from Thread windows its is in suspended state. Programming Language C#.Net Framework 2.0
2
1545
by: WXS | last post by:
When I see things in .NET 2.0 like obsoletion of suspend/resume because of the public reason MS gives of they think people are using them inappropriately.. use mutex, monitor and other synchronization objects instead and oh by the way you shouldn't be using them as they can cause deadlock and other major problems, screams bug or threading architecture issue and lack of willingness or priority to correct. In reality those API's are for...
15
2083
by: WXS | last post by:
When I see things in .NET 2.0 like obsoletion of suspend/resume because of the public reason MS gives of they think people are using them inappropriately.. use mutex, monitor and other synchronization objects instead and oh by the way you shouldn't be using them as they can cause deadlock and other major problems, screams bug or threading architecture issue and lack of willingness or priority to correct. In reality those API's are for...
6
1418
by: Robert Speck | last post by:
Hi there, Can anyone shed anymore light on why "Thread.Suspend()" has been deprecated by MSFT beyond what MSDN says about it. I'm not sure if I quite appreciate the various pitfalls they discuss but using it under certain circumstances still seems reasonable. For instance, I want to display a small modal dialog with a "Cancel" button which allows the user to abort a background thread. If the user clicks this button, I then want to prompt...
6
10280
by: Buddy Home | last post by:
Hello, I want to understand whats the best way to write code to replace Thread.Suspend, Thread.Resume and Thread.Abort. I have lots of code calling these existing methods and want to minimize the risk of changing the code everywhere so here is what I think I could do, which is to create my own ThreadWrapper class which inherits from Thread and which has these three methods already defined but does it a different way and then my...
3
6066
by: =?Utf-8?B?TWFyayBDaGFubmluZw==?= | last post by:
I have a code which registers all threads with a thread dump class. At intervals this thread dump class will dump the stack trace of all threads. As calling StackTrace(threadtoDump) from a different thread other than the treadToDump the threadToDump must be suspended otherwise a ThreadStateException gets thrown. However under .NET 2.0 System.Threading.Thread.Suspend/Resume have been marked as obsolete with reference to better methods of...
0
10003
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9851
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10504
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
8055
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
7213
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5897
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
6099
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
4312
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3327
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.