Windows: bajo ¿Qué circunstancias pueden no devolverse inmediatamente? -- windows camp Relacionados El problema

Windows: Under what circumstances might SetEvent() not return immediately?


1
vote

problema

Español

Tengo un hilo que, cuando su función sale de su bucle (la salida está activada por un evento), hace un poco de limpieza y luego establece un evento diferente para que un hilo maestro sepa que se realiza.

Sin embargo, en algunas circunstancias, SetEvent () parece no volver después de que establezca el evento 'He terminado' del hilo.

Este hilo es parte de una DLL y el problema parece ocurrir después de que se haya cargado / adjunto el DLL, se inició el hilo, el hilo terminó y el DLL separado / descargado varias veces sin la aplicación cerrada en el medio. El número de veces que esta secuencia debe repetirse antes de que ocurra este problema es variable.

En caso de que sea escéptico que sepa de qué estoy hablando, he determinado lo que está sucediendo al hormetizar la llamada de SetEvent () con las llamadas a OutputDebugstring (). La salida antes de SetEvent () aparece. Luego, el hilo de espera produce una salida que indica que se ha establecido el evento.

Sin embargo, la segunda convocatoria de OutputDebugString () en el hilo salido (el después de la SETEVENT ()) nunca se produce, o al menos su cadena nunca aparece. Si esto sucede, la aplicación se bloquea unos momentos más adelante.

(Tenga en cuenta que se agregaron las llamadas a la prohibición de salida () después de que el problema comenzó a ocurrir, por lo que es poco probable que se colgues allí, en lugar de en SETEVENT ()).

No estoy totalmente seguro de lo que causa el accidente, pero se produce en el mismo hilo en el que selevent () no regresó de inmediato (he estado rastreando / saliendo de las ID de hilo). Supongo que es posible que SETEFENT () finalmente regrese, por qué punto el contexto al que está regresando se ha desaparecido / inválido, pero ¿qué podría causar tal retraso?

Resulta que he estado cegado mirando este código durante tanto tiempo, y ni siquiera se le ocurrió para verificar el código de retorno. He terminado de mirarlo por hoy, así que sabré lo que está regresando ( si está regresando) el lunes y editaré esta pregunta con esa información entonces.

Actualización: Cambié el código (maestro) para esperar a que el hilo salga en lugar de que establezca el evento, y elimine la llamada SETEVENT () desde el hilo esclavo. Esto cambió la naturaleza del error: ahora, en lugar de no volver de SetEvent (), no sale del hilo en absoluto y todo se cuelga.

Esto indica que el problema no está con SetEvent (), pero algo más profundo. No tengo idea de qué, sin embargo, pero es bueno no perseguir a ese callejón ciego.

Actualización (Feb 13/09):
Resultó que el problema era más profundo de lo que pensaba cuando hice esta pregunta. Jdigital (y probablemente otros) ha clavado bastante el problema subyacente: estábamos tratando de descargar un hilo como parte del proceso de desprendimiento de una DLL.

Esto, como no me di cuenta en ese momento, sino que desde entonces descubrí a través de la investigación aquí y en otros lugares (el blog de Raymond Chen, por ejemplo), es algo muy malo.

El problema fue, debido a la forma en que se codificó y la forma en que se estaba comportando, no es obvio que ese era el problema subyacente, era camuflado como todo tipo de otros malos comportamientos que tuve para atravesar.

Algunas de las sugerencias aquí me ayudaron a hacer eso, así que estoy agradecido a todos los que contribuyeron. ¡Gracias!

Original en ingles

I have a thread that, when its function exits its loop (the exit is triggered by an event), it does some cleanup and then sets a different event to let a master thread know that it is done.

However, under some circumstances, SetEvent() seems not to return after it sets the thread's 'I'm done' event.

This thread is part of a DLL and the problem seems to occur after the DLL has been loaded/attached, the thread started, the thread ended and the DLL detached/unloaded a number of times without the application shutting down in between. The number of times this sequence has to be repeated before this problem happens is variable.

In case you are skeptical that I know what I'm talking about, I have determined what's happening by bracketing the SetEvent() call with calls to OutputDebugString(). The output before SetEvent() appears. Then, the waiting thread produces output that indicates that the Event has been set.

However, the second call to OutputDebugString() in the exiting thread (the one AFTER SetEvent() ) never occurs, or at least its string never shows up. If this happens, the application crashes a few moments later.

(Note that the calls to OutputDebugString() were added after the problem started occurring, so it's unlikely to be hanging there, rather than in SetEvent().)

I'm not entirely sure what causes the crash, but it occurs in the same thread in which SetEvent() didn't return immediately (I've been tracking/outputting the thread IDs). I suppose it's possible that SetEvent() is finally returning, by which point the context to which it is returning is gone/invalid, but what could cause such a delay?

It turns out that I've been blinded by looking at this code for so long, and it didn't even occur to me to check the return code. I'm done looking at it for today, so I'll know what it's returning (if it's returning) on Monday and I'll edit this question with that info then.

Update: I changed the (master) code to wait for the thread to exit rather than for it to set the event, and removed the SetEvent() call from the slave thread. This changed the nature of the bug: now, instead of failing to return from SetEvent(), it doesn't exit the thread at all and the whole thing hangs.

This indicates that the problem is not with SetEvent(), but something deeper. No idea what, yet, but it's good not to be chasing down that blind alley.

Update (Feb 13/09):
It turned out that the problem was deeper than I thought when I asked this question. jdigital (and probably others) has pretty much nailed the underlying problem: we were trying to unload a thread as part of the process of detaching a DLL.

This, as I didn't realize at the time, but have since found out through research here and elsewhere (Raymond Chen's blog, for example), is a Very Bad Thing.

The problem was, because of the way it was coded and the way it was behaving, it not obvious that that was the underlying problem - it was camouflaged as all sorts of other Bad Behaviours that I had to wade through.

Some of the suggestions here helped me do that, so I'm grateful to everyone who contributed. Thank you!

  

Lista de respuestas

2
 
vote
vote
La mejor respuesta
 

¿Quién está descargando la DLL y a qué hora se realiza la descarga? Me pregunto si hay un problema de tiempo aquí donde la DLL se descarga antes de que se haya ejecutado el hilo hasta la finalización.

 

Who is unloading the DLL and at what time is the unload done? I am wondering if there is a timing issue here where the DLL is unloaded before the thread has run to completion.

 
 
2
 
vote

¿Está usted lefernncia de un Excel (.xls) Keynote (.key.zip) Numbers (.numbers.zip) Pages (.pages.zip) PDF (.pdf) Powerpoint (.ppt) Word (.doc) Rich Text Format (.rtf) Rich Text Format Directory (.rtfd.zip) Keynote '09 (.key) Numbers '09 (.numbers) Pages '09 (.pages) 0 para pasar a Excel (.xls) Keynote (.key.zip) Numbers (.numbers.zip) Pages (.pages.zip) PDF (.pdf) Powerpoint (.ppt) Word (.doc) Rich Text Format (.rtf) Rich Text Format Directory (.rtfd.zip) Keynote '09 (.key) Numbers '09 (.numbers) Pages '09 (.pages) 1111 ? Es más probable que la referencia del manejo del evento sea inválida y el accidente es una violación de acceso (es decir, acceder a la basura).

 

Are you dereferncing a HANDLE * to pass to SetEvent? It's more likely that the event handle reference is invalid and the crash is an access violation (i.e., accessing garbage).

 
 
0
 
vote

Es posible que desee usar Windbg para atrapar el choque y examinar la pila.

 

You might want to use WinDbg to catch the crash and examine the stack.

 
 
0
 
vote

¿Por qué necesita establecer un evento en el hilo esclavo para activar el hilo maestro que se realiza el hilo? Simplemente salga del hilo, el hilo maestro de llamadas debe esperar a que el subproceso del trabajador salga, ejemplo pseudo código -

  Master {    TerminateEvent = CreateEvent ( ... ) ;    ThreadHandle = BeginThread ( Slave, (LPVOID) TerminateEvent ) ;    ...    Do some work    ...    SetEvent ( TerminateEvent ) ;    WaitForSingleObject ( ThreadHandle, SOME_TIME_OUT ) ;    CloseHandle ( TerminateEvent ) ;    CloseHandle ( ThreadHandle ) ;  }  Slave ( LPVOID ThreadParam ) {    TerminateEvent = (HANDLE) ThreadParam ;    while ( WaitForSingleObject ( TerminateEvent, SOME__SHORT_TIME_OUT ) == WAIT_TIMEOUT )    {        ...        Do some work        ...    } }   

Hay muchas condiciones de error y estados para verificar, pero esta es la esencia de cómo lo hago normalmente.

Si puede conseguirlo, obtenga este libro, cambió mi vida con respecto al desarrollo de Windows cuando lo leo por primera vez muchos, hace muchos años.

Windows avanzado: la Guía del desarrollador de la API Win32 para Windows NT 3.5 y Windows 95 (Paperback), por Jeffrey Richter (Autor)

 

Why do you need to set an event in the slave thread to trigger to the master thread that the thread is done? just exit the thread, the calling master thread should wait for the worker thread to exit, example pseudo code -

Master {    TerminateEvent = CreateEvent ( ... ) ;    ThreadHandle = BeginThread ( Slave, (LPVOID) TerminateEvent ) ;    ...    Do some work    ...    SetEvent ( TerminateEvent ) ;    WaitForSingleObject ( ThreadHandle, SOME_TIME_OUT ) ;    CloseHandle ( TerminateEvent ) ;    CloseHandle ( ThreadHandle ) ;  }  Slave ( LPVOID ThreadParam ) {    TerminateEvent = (HANDLE) ThreadParam ;    while ( WaitForSingleObject ( TerminateEvent, SOME__SHORT_TIME_OUT ) == WAIT_TIMEOUT )    {        ...        Do some work        ...    } } 

There are lots of error conditions and states to check for but this is the essence of how I normally do it.

If you can get hold of it, get this book, it changed my life with respect to Windows development when I first read it many, many years ago.

Advanced Windows: The Developer's Guide to the Win32 Api for Windows Nt 3.5 and Windows 95 (Paperback), by Jeffrey Richter (Author)

 
 

Relacionados problema

48  Los mejores clientes de subversión para Windows Vista (64bit) [CERRADO]  ( Best subversion clients for windows vista 64bit ) 
Según lo que actualmente representa, esta pregunta no es un buen ajuste para nuestro Q & Amp; un formato. Esperamos que las...

39  Registre el programa Windows con el protocolo de correo por correo electrónico  ( Register windows program with the mailto protocol programmatically ) 
¿Cómo lo hago, así que mailto: enlaces se registrarán con mi programa? ¿Cómo manejaría entonces ese evento en mi programa? La mayoría de las soluciones ...

20  Proyecto de configuración de Visual Studio - por Configuración del Registro de usuarios  ( Visual studio setup project per user registry settings ) 
Estoy tratando de mantener un proyecto de configuración en Visual Studio 2003 (Sí, es una aplicación heredada). El problema que tenemos en este momento es q...

56  ¿La mejor manera de acceder a Exchange usando PHP?  ( Best way to access exchange using php ) 
Estoy escribiendo una aplicación CMS en PHP y uno de los requisitos es que debe poder interactuar con el servidor de Exchange del cliente. He escrito esta fun...

39  Archivos de ayuda de Windows - ¿Cuáles son las opciones?  ( Windows help files what are the options ) 
De nuevo en los viejos tiempos, la ayuda no era trivial pero es posible: generar un archivo Funky .RTF con etiquetas especiales, ejecútelo a través de un comp...

63  Embeding Windows Media Player para todos los navegadores  ( Embedding windows media player for all browsers ) 
Editar: Esta pregunta fue escrita en 2008, que fue como 3 años de internet. Si esta pregunta sigue siendo relevante para su entorno, acepte mis condolencias...

64  Montón de corrupción bajo Win32; ¿Cómo localizar?  ( Heap corruption under win32 how to locate ) 
Estoy trabajando en una aplicación de MultiShreaded que está corrompiendo el montón. Las herramientas habituales para localizar esta corrupción parecen ser ...

49  Obtener una vista previa JPEG de un PDF en Windows?  ( Get a preview jpeg of a pdf on windows ) 
Tengo una aplicación multiplataforma (Python) que necesita generar una vista previa de JPEG de la primera página de un PDF. en la Mac estoy desplazando SIP...

21  Linux Shell equivalente en IIS  ( Linux shell equivalent on iis ) 
Como desarrollador de lámparas, considerando mudarse a una plataforma .NET IIS, una de mis inquietudes es la pérdida de productividad debido a la falta de she...

38  ¿Qué es una mejor alternativa de copia de archivo que el valor predeterminado de Windows? [cerrado]  ( What is a better file copy alternative than the windows default ) 
cerrado. Esta pregunta es off-topic . Actualmente no está aceptando respuestas. CERRADO 9 años . ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos