Red de conocimiento informático - Conocimiento del nombre de dominio - Cómo iniciar un hilo en una DLL

Cómo iniciar un hilo en una DLL

Este método no es diferente de un EXE normal.

Capítulo 6 Conceptos básicos de subprocesos

1. ¿Cuáles son las diferencias y conexiones entre procesos y subprocesos?

l Cada proceso requiere al menos un hilo.

l Un proceso consta de dos partes: el objeto del núcleo del proceso y el espacio de direcciones. Los subprocesos también se componen de dos partes: el objeto del núcleo del subproceso, que utiliza el sistema operativo para gestionar los subprocesos. La pila de subprocesos se utiliza para mantener todos los parámetros de función y variables locales requeridas por el subproceso para ejecutar el código.

l El proceso está inactivo. Un proceso nunca realiza ninguna operación; es sólo un contenedor de subprocesos. Un hilo siempre se crea en un entorno de proceso y todo su ciclo de vida transcurre en ese proceso.

l Si hay varios subprocesos ejecutándose en un entorno de proceso, entonces estos subprocesos comparten un espacio de direcciones. Estos hilos pueden ejecutar el mismo código y manipular los mismos datos. Estos subprocesos también tienen acceso a los identificadores de objetos del kernel porque la tabla de identificadores depende de cada proceso, no de cada subproceso.

l Los procesos utilizan más recursos del sistema que los subprocesos. De hecho, un hilo tiene sólo un objeto del núcleo y una pila, mantiene muy pocos registros y, por lo tanto, requiere muy poca memoria. Por lo tanto, siempre se debe intentar resolver los problemas de programación agregando subprocesos y evitando crear nuevos procesos. Sin embargo, muchos diseños de programación se implementan mejor mediante múltiples procesos.

2. ¿Cómo utilizar la función _beginthreadex?

Esta función es la misma que la función CreateThread excepto que es necesario convertir el tipo del parámetro de llamada.

3. ¿Cómo utilizar la función CreateThread?

Cuando se llama a CreateThread, el sistema crea un objeto de núcleo de subproceso. El objeto del núcleo del subproceso no es el subproceso en sí, sino una estructura de datos más pequeña utilizada por el sistema operativo para administrar los subprocesos. Una vez que ya no necesite acceder al núcleo del subproceso, debe prestar atención a llamar a la función CloseHandle para cerrar el identificador del subproceso. Se debe evitar el uso de la función CreateThread porque algunas funciones de la biblioteca de tiempo de ejecución de C/C pueden provocar pérdidas de memoria.

Significado del parámetro

lpThreadAttributes Si se pasa NULL, el hilo utilizará los atributos de seguridad predeterminados. Si desea que todos los procesos secundarios hereden el identificador del objeto de subproceso, debe inicializar su miembro bInheritHandle en TRUE.

dwStackSize establece el espacio de direcciones de la pila de subprocesos. Si es distinto de cero, la función reservará toda la memoria y la asignará a la pila del subproceso. Si es 0, CreateThread reserva un área y asigna a la pila de subprocesos la cantidad de memoria indicada por la información del modificador del vinculador /STACK incrustada en el archivo .exe por el vinculador.

lpStartAddress La dirección de la función del hilo.

lpParameter El parámetro pasado a la función de subproceso.

dwCreationFlags Si es 0, el hilo se programa inmediatamente después de la creación. Si CREATE_SUSPENDED, el hilo se suspende después de la inicialización del sistema.

LpThreadId se utiliza para guardar el ID asignado por el sistema al nuevo hilo.

4. ¿Cómo terminar el hilo?

(1) Devuelve la función Thread (este es el método más útil).

Esta es la única manera de garantizar que todos los recursos de subprocesos se borre correctamente.

Si el hilo puede regresar, puede asegurarse de lo siguiente: Todos los objetos C creados en la función del hilo serán revocados correctamente por su función de deshacer. El sistema operativo liberará correctamente la memoria utilizada por la pila de subprocesos. El sistema establecerá el código de salida del hilo en el valor de retorno de la función del hilo. El sistema disminuye el recuento de uso del objeto del núcleo del subproceso.

(2) Llame a la función ExitThread (es mejor no utilizar este método).

Esta función finalizará el hilo y hará que el sistema operativo borre todos los recursos del sistema operativo utilizados por el hilo. Sin embargo, los recursos C (como los objetos de clase C) no se revocan.

(3) Llame a la función TerminateThread (este método debe evitarse).

TerminateThread puede terminar cualquier hilo. La función de terminación de hilo es una función que se ejecuta de forma asincrónica. Para determinar que el hilo ha terminado, se debe llamar a WaitForSingleObject o una función similar. Cuando un hilo se desactiva usando Return o llamando a ExitThread, la pila de memoria del hilo también se desactiva. Sin embargo, si se utiliza TerminateThread, la pila del subproceso no se destruye hasta que el proceso propietario finalice su operación.

(4) El proceso que contiene el hilo finaliza (este método debe evitarse).

Debido a que todo el proceso se ha cerrado, todos los recursos utilizados por el proceso deben haberse eliminado. Esto es como llamar a TerminateThread desde cada hilo restante. Esto significa que no se realizó una limpieza adecuada de la aplicación, es decir, no se llamaron las funciones de deshacer del objeto C, no se transfirieron datos al disco, etc.

Una vez que un subproceso ya no se ejecuta, ningún otro subproceso en el sistema puede manejar el identificador del subproceso. Sin embargo, otros subprocesos pueden llamar a GetExitcodeThread para verificar si el subproceso identificado por hThread ha terminado. Si se cancela, determine su código de salida.

5. ¿Por qué no utilizar las funciones _beginthread y _endthread?

En comparación con la función _beginthreadex, _beginthread tiene menos parámetros y más restricciones. No puede crear subprocesos suspendidos, no puede obtener el ID del subproceso, _endthread no tiene parámetros, el código de salida del subproceso debe ser 0 y _endthread cierra internamente el identificador del subproceso para que no pueda acceder a él correctamente una vez que salga.

6. ¿Cómo referenciar el kernel de un proceso o hilo?

HANDLE GetCurrentProcess( );

HANDLE GetCurrentThread(

Ambas funciones devolverán el pseudo identificador del proceso del hilo que llama o el pseudo identificador de el objeto del núcleo del hilo. Los pseudoidentificadores solo se pueden utilizar en el proceso o subproceso actual y otros subprocesos o procesos no podrán acceder a ellos. La función no crea nuevos identificadores en la tabla de identificadores del proceso de creación. Llamar a estas funciones no afecta la cantidad de veces que se utiliza el objeto del núcleo del proceso o del subproceso. Si se llama a CloseHandle y se pasa un pseudohandle como parámetro, CloseHandle ignora la llamada a la función y devuelve FALSO.

DWORD GetCurrentProcessId( );

DWORD GetCurrentThreadId(

Estas dos funciones permiten que un hilo consulte la ID única de su proceso o su propia ID única. .

7. ¿Cómo convertir un pseudo identificador en un identificador real?

HANDLE hProcessFalse = NULL;

HANDLE hProcessTrue = NULL;

HANDLE hThreadFalse = NULL;

HANDLE hThreadTrue = NULL;

HANDLE hThreadFalse = NULL;

HANDLE hThreadFalse = NULL; p>

hProcessFalse = GetCurrentProcess(

hThreadFalse = GetCurrentThread(

);

Obtenga el identificador del hilo real:

DuplicateHandle( hProcessFalse, hThreadFalse, hThreadFalse , hThreadTrue = NULL);

HANDLE hThreadFalse, hProcessFalse, & hThreadTrue, 0, FALSE, DUPLICATE_SAME_ACCESS ) ;

Obtenga el identificador real del proceso:

DuplicateHandle (hProcessFalse, hProcessFalse, & hProcessTrue, 0, FALSE, DUPLICATE_SAME_ACCESS);

Porque DuplicateHandle aumenta el número de veces que se usa un objeto específico, el identificador de destino debe pasarse a CloseHandle después de completar la operación de duplicar el identificador del objeto, reduciendo así el número de veces que se usa el objeto.