Possible huge clue into unmanged/managed problem

  • Thread starter Thread starter _BNC
  • Start date Start date
B

_BNC

Recently I had posted a query about intermittent problems with a
C++/Interop scheme (unmanaged C DLL wrapped in unmanaged C++,
wrapped in managed C++, all accessed by C#). The system works fine
when unstressed, but fails under stress.

Well...I just noticed short mention in Prosise's book, of all places,
re threading. He indicated that the behavior of unmanaged code within
managed threads is not predictable. I had thought that the organized
internal alloc/shutdown within the embedded unmanaged classes was
good enough to keep things in line. Maybe not.

Do I need to take all the unmanaged code out to an UNmanaged thread?
(Yechh!) Is this documented anywhere?

_B
 
I wouldn't think so. What is the context of Prosise' statement? I'm sure it
won't infringe copywrites if you post a replication/summation

--
Regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
The Microsoft Office Web Components Black Book with .NET
Now Available @ http://tinyurl.com/27cok
 
I wouldn't think so. What is the context of Prosise' statement? I'm sure it
won't infringe copywrites if you post a replication/summation

I doubt that Jeff would mind. p668, under 'terminating threads':

"Abort throws a ThreadAbortException in the targeted thread, causing the
thread to edn. The thread might not end immediately; in fact, it's not
guaranteed to end at all. If the thread has called out to unmanaged code,
for example, and hasn't yet returned, it doesn't terminate until it begins
executing managed code again. ..."

I hadn't expected much on unmanaged code in Jeff's book, but I still
haven't got a solid grip on what is going on in mgd/unmgd, so in my spare
time I've been combing through all my books and references to unmanaged
code.

The scenario above could happen, I think, as the original code was
designed to loop til it got a result-- or until its thread was aborted.
It hadn't occurred to me that the *managed thread* can no longer control
some of the code inside the thread. The symptoms don't all match up,
but that's par for this program.
 
I didn't read your old post about your problem but
I think a good design is to avoid methods like Thread.Abort
or / and TerminateThread since they always cause you
problem in the "long" run. I think a more controlled signal
is needed when you whish to shut down your thread.
You could use an w32 event object for this notification,
it is possible to access these from managed code as well

// daniel
 
I'm wondering out loud if the CLR team cannot provide a cleaner way to
terminate a thread that would be internally implemented?

--
Regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
The Microsoft Office Web Components Black Book with .NET
Now Available @ http://tinyurl.com/27cok
 
The CLR depends on the OS service offered to terminate a (OS) thread, and
it's that service (TerminateThread) which is "dangerous by nature".

Willy.

Alvin Bruney said:
I'm wondering out loud if the CLR team cannot provide a cleaner way to
terminate a thread that would be internally implemented?

--
Regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
The Microsoft Office Web Components Black Book with .NET
Now Available @ http://tinyurl.com/27cok
----------------------------------------------------------


Daniel Petersson said:
I didn't read your old post about your problem but
I think a good design is to avoid methods like Thread.Abort
or / and TerminateThread since they always cause you
problem in the "long" run. I think a more controlled signal
is needed when you whish to shut down your thread.
You could use an w32 event object for this notification,
it is possible to access these from managed code as well

// daniel
 
You simply have to call return from the thread method to terminate a thread
the clean way.

Alvin Bruney said:
I'm wondering out loud if the CLR team cannot provide a cleaner way to
terminate a thread that would be internally implemented?

--
Regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
The Microsoft Office Web Components Black Book with .NET
Now Available @ http://tinyurl.com/27cok
----------------------------------------------------------


Daniel Petersson said:
I didn't read your old post about your problem but
I think a good design is to avoid methods like Thread.Abort
or / and TerminateThread since they always cause you
problem in the "long" run. I think a more controlled signal
is needed when you whish to shut down your thread.
You could use an w32 event object for this notification,
it is possible to access these from managed code as well

// daniel
 
cody said:
You simply have to call return from the thread method to terminate a
thread
the clean way.

And what if the thread is blocked or is in an infinite loop?
There is nothing wrong with Thread.Abort as long as you call it
synchronously. When called asynchronously you have to terminate the process
when done or unload the application domain if not running in the primary
domain.

Willy.
 
What do you mean with "terminate the process"? Why should I have to
terminate the whole application if I only want to terminate one thread? And
if a terminate the last thread in an application shouldn't the process be
terminated automatically by the system?
 
If you happen to abort a thread asynchronously, that means an exception can
bet thrown at any moment during program execution, you possibly have
corrupted the application state.
Consider following thread procedure

void SomeProc()
{
lock(myLock)
{
}
}
, when the exception is thrown during the execution of the finalize clause
(compiler generated from lock()), chances are that the lock is not released.
If it happens that you are executing unmanaged code during Abort, chances
are that locks held by your unmanaged code will not being released, buffers
not freed, semaphores not cleared etc.
If it happens during managed execution of global state initialization
(static's), you'll end with incorrectly initialized global state.

So, I think it's clear there is no other option then to exit the process or
throw away the application domain.

Not sure what you mean with:
terminate the last thread in an application shouldn't the process be
terminated automatically by the system?
calling Thread.Abort on your current thread, is a synchronous Abort
(synchronous exception), and yes if it happens on the last managed thread in
the application, the CLR will shutdown the process.

Willy.
 
I gather you are saying that there needs to be an OS update for this to be
implemented cleanly right?
So isn't long horn around the corner?

--
Regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
The Microsoft Office Web Components Black Book with .NET
Now Available @ http://tinyurl.com/27cok
----------------------------------------------------------


Willy Denoyette said:
The CLR depends on the OS service offered to terminate a (OS) thread, and
it's that service (TerminateThread) which is "dangerous by nature".

Willy.

Alvin Bruney said:
I'm wondering out loud if the CLR team cannot provide a cleaner way to
terminate a thread that would be internally implemented?

--
Regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
The Microsoft Office Web Components Black Book with .NET
Now Available @ http://tinyurl.com/27cok
----------------------------------------------------------


Daniel Petersson said:
I didn't read your old post about your problem but
I think a good design is to avoid methods like Thread.Abort
or / and TerminateThread since they always cause you
problem in the "long" run. I think a more controlled signal
is needed when you whish to shut down your thread.
You could use an w32 event object for this notification,
it is possible to access these from managed code as well

// daniel

:

I wouldn't think so. What is the context of Prosise' statement? I'm
sure it
won't infringe copywrites if you post a replication/summation

I doubt that Jeff would mind. p668, under 'terminating threads':

"Abort throws a ThreadAbortException in the targeted thread, causing
the
thread to edn. The thread might not end immediately; in fact, it's not
guaranteed to end at all. If the thread has called out to unmanaged
code,
for example, and hasn't yet returned, it doesn't terminate until it
begins
executing managed code again. ..."

I hadn't expected much on unmanaged code in Jeff's book, but I still
haven't got a solid grip on what is going on in mgd/unmgd, so in my
spare
time I've been combing through all my books and references to unmanaged
code.

The scenario above could happen, I think, as the original code was
designed to loop til it got a result-- or until its thread was aborted.
It hadn't occurred to me that the *managed thread* can no longer
control
some of the code inside the thread. The symptoms don't all match up,
but that's par for this program.
 
There is nothing wrong with Thread.Abort as long as you call it
synchronously.
No because the abort can fire on the thread in a way that the thread is not
prepared for and cause problems. For instance, consider this thread code

try
some code
finally //thread abort fires here as entry to finally block is being
prepared for exection by executing thread
save the world before exiting

--
Regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
The Microsoft Office Web Components Black Book with .NET
Now Available @ http://tinyurl.com/27cok
 
You can't terminate threads because the software execution model of
computer processes is not transactioned. Like, in a database you can
do:

BEGIN TRANS
UPDATE A
UPDATE B
COMMIT

and the updates to A and B either both take place or neither complete.
At the OS level (which .NET runs at), you get

UPDATE A
UPDATE B

And if you halted the thread, you might have the partial update of A,
maybe A and part of B, or maybe neither, and there's no way of knowing.
This can wreak all sorts of havoc. In the classic example, let's say
A meant, update the inventory information, and B meant, update the
sales information, then, breaking in the middle would cause your
inventory and or sales to become hosed and therefor worthless.

It gets worse because you can have all sorts of weird problems going at
the OS level. For example, lets say you had a thread that opened a
file and started writing to it. What's in the file when you just stop
it randomly? You don't know. You just lost the file.

To do this correctly, you have to make sure that threads are only
stopped at known points. This is what semaphores, mutexes, and signals
and XXXInvoke are all for. They let you as a programmer say, well, I
really want to stop here, so I can. A really simple way to make a
thread shut down at some arbitrary time is to use an abort flag.

So you have a thread A

if (abort)
stop

do some work

if (abort)
stop

and then thread B can set the abort flag to true if it is time to stop,
and you can design thread A to only look for the abort flag when it is
time to stop.
 
, when the exception is thrown during the execution of the finalize clause
(compiler generated from lock()), chances are that the lock is not
released.
If it happens that you are executing unmanaged code during Abort, chances
are that locks held by your unmanaged code will not being released,
buffers not freed, semaphores not cleared etc.
If it happens during managed execution of global state initialization
(static's), you'll end with incorrectly initialized global state.

So, I think it's clear there is no other option then to exit the process
or throw away the application domain.

Now I understand. But you are not forced to do so. You can continue running
the app risking to lose data when the app crashes due to its inconsistent
state but there is a good chance everthing runs still fine.
calling Thread.Abort on your current thread, is a synchronous Abort
(synchronous exception), and yes if it happens on the last managed thread
in the application, the CLR will shutdown the process.

Yes I meant exactly that.
 
cody said:
Now I understand. But you are not forced to do so. You can continue
running the app risking to lose data when the app crashes due to its
inconsistent state but there is a good chance everthing runs still fine.

You won't let it run with possible inconsistent state do you?, or with a
risk that it deadlocks?
Clearly by calling Thread.Abort asynchronously you effectively introduced a
"bug", so only thing I can suggest is - don't do it.


Willy.
 
Back
Top