English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Hilo definido como la trayectoria de ejecución de un programa. Cada hilo define un flujo de control único. Si su aplicación implica operaciones complejas y costosas, es beneficioso establecer diferentes trayectorias de ejecución de hilos, con cada hilo realizando un trabajo específico.
Un hilo esProceso ligeroUn ejemplo común de uso de hilos es la implementación de programación paralela en sistemas operativos modernos. El uso de hilos ahorra el desperdicio de ciclos de CPU y mejora la eficiencia de la aplicación.
Hasta ahora, el programa que hemos escrito es un proceso que ejecuta un solo hilo como ejemplo de ejecución de aplicación. Sin embargo, de esta manera, la aplicación puede ejecutar solo una tarea a la vez. Para ejecutar múltiples tareas simultáneamente, se puede dividir en hilos más pequeños.
El ciclo de vida del hilo comienza cuando se crea el objeto de la clase System.Threading.Thread, y termina cuando el hilo se termina o completa la ejecución.
A continuación, se enumeran varios estados en el ciclo de vida del hilo:
Estado no iniciado: estado cuando el ejemplo de hilo se ha creado pero no se ha llamado al método Start.
Estado listo: estado cuando el hilo está listo para ejecutarse y espera un ciclo de CPU.
Estado no ejecutable: En las siguientes circunstancias, el hilo no es ejecutable:
Se ha llamado al método Sleep
Se ha llamado al método Wait
A través de I/Operación de bloqueo
Estado muerto: estado cuando el hilo ha completado la ejecución o ha sido interrumpido.
En C#,System.Threading.Thread La clase se utiliza para el trabajo de hilos. Permite crear y acceder a hilos individuales en aplicaciones multihilo. El primer hilo ejecutado en el proceso se llamaHilo principal.
Cuando un programa C# comienza a ejecutarse, el hilo principal se crea automáticamente. Utilice Thread La clase creada por el hilo se llama desde el subhilo del hilo principal. Puede usar la clase Thread CurrentThread Acceso a atributos de hilera.
El siguiente programa muestra la ejecución del hilo principal:
using System; using System.Threading; namespace MultithreadingApplication { class MainThreadProgram { static void Main(string[] args) { Thread th = Thread.CurrentThread; th.Name = "MainThread"; Console.WriteLine("This is {0}", th.Name); Console.ReadKey(); } } }
Cuando el código anterior se compila y ejecuta, se producirá el siguiente resultado:
This is MainThread
La tabla a continuación enumera Thread Algunos métodos comunes de una clase Atributos:
Atributos | Descripción |
---|---|
CurrentContext | Obtener el contexto actual en el que se está ejecutando la hilera. |
CurrentCulture | Obtener o establecer la regionalidad actual de la hilera. |
CurrentPrincipal | Obtener o establecer el responsable actual de la hilera (para la seguridad basada en roles). |
CurrentThread | Obtener la hilera que se está ejecutando actualmente. |
CurrentUICulture | Obtener o establecer la regionalidad actual utilizada por el administrador de recursos para buscar recursos específicos de regionalidad en tiempo de ejecución. |
ExecutionContext | Obtener un objeto ExecutionContext, que contiene información sobre varios contextos de la hilera actual. |
IsAlive | Obtiene un valor que indica el estado de ejecución del hilo actual. |
IsBackground | Obtiene o establece un valor que indica si un hilo es un hilo de fondo. |
IsThreadPoolThread | Obtiene un valor que indica si el hilo pertenece al pool de hilos de administración. |
ManagedThreadId | Obtiene el identificador único del hilo de administración. |
Name | Obtiene o establece el nombre del hilo. |
Priority | Obtiene o establece un valor que indica la prioridad de planificación del hilo. |
ThreadState | Obtiene un valor que contiene el estado actual del hilo. |
La tabla a continuación enumera Thread Algunos métodos comunes de una clase Método:
Número | Nombre del método & Descripción |
---|---|
1 | public void Abort() Lanza ThreadAbortException en el hilo que llama a este método para comenzar el proceso de terminación de este hilo. Llamar a este método generalmente termina el hilo. |
2 | public static LocalDataStoreSlot AllocateDataSlot() Asigna un slot de datos sin nombre en todas las hebras. Para obtener un mejor rendimiento, utilice campos marcados con la propiedad ThreadStaticAttribute. |
3 | public static LocalDataStoreSlot AllocateNamedDataSlot(
string name) Asigna un slot de datos nombrado en todas las hebras. Para obtener un mejor rendimiento, utilice campos marcados con la propiedad ThreadStaticAttribute. |
4 | public static void BeginCriticalRegion() Notifica al anfitrión que se va a ingresar en una región de código, en la que el aborto del hilo o la excepción no tratada podría dañar otras tareas en el dominio de la aplicación. |
5 | public static void BeginThreadAffinity() Notifica al anfitrión que el código de host va a ejecutar instrucciones que dependen del identificador de hilo del sistema operativo físico actual. |
6 | public static void EndCriticalRegion() Notifica al anfitrión que se va a ingresar en una región de código, en la que el aborto del hilo o la excepción no tratada solo afecta la tarea actual. |
7 | public static void EndThreadAffinity() Notifica al anfitrión que el código de host ha ejecutado las instrucciones que dependen del identificador de hilo del sistema operativo físico actual. |
8 | public static void FreeNamedDataSlot(string name) 为进程中的所有线程消除名称与槽之间的关联。为了获得更好的性能,请改用以 ThreadStaticAttribute 属性标记的字段。 |
9 | public static Object GetData(
LocalDataStoreSlot slot
) 在当前线程的当前域中从当前线程上指定的槽中检索值。为了获得更好的性能,请改用以 ThreadStaticAttribute 属性标记的字段。 |
10 | public static AppDomain GetDomain() 返回当前线程正在其中运行的当前域。 |
11 | public static AppDomain GetDomainID() 返回唯一的应用程序域标识符。 |
12 | public static LocalDataStoreSlot GetNamedDataSlot(
string name
) 查找已命名的数据槽。为了获得更好的性能,请改用以 ThreadStaticAttribute 属性标记的字段。 |
13 | public void Interrupt() 中断处于 WaitSleepJoin 线程状态的线程。 |
14 | public void Join() 在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻塞调用线程,直到某个线程终止为止。此方法有不同的重载形式。 |
15 | public static void MemoryBarrier() 按如下方式同步内存存取:执行当前线程的处理器在对指令重新排序时,不能采用先执行 MemoryBarrier 调用之后的内存存取,再执行 MemoryBarrier 调用之前的内存存取的方式。 |
16 | public static void ResetAbort() 取消为当前线程请求的 Abort。 |
17 | public static void SetData(
LocalDataStoreSlot slot,
Object data
) 在当前正在运行的线程上为此线程的当前域在指定槽中设置数据。为了获得更好的性能,请改用以 ThreadStaticAttribute 属性标记的字段。 |
18 | public void Start() 开始一个线程。 |
19 | public static void Sleep(
int millisecondsTimeout
) detener temporalmente el hilo por un tiempo. |
20 | public static void SpinWait(
int iterations
) que provoca que el hilo espere la cantidad de tiempo definida por el parámetro iterations. |
21 | public static byte VolatileRead(
ref byte address
) public static double VolatileRead( ref double address ) public static int VolatileRead( ref int address ) public static Object VolatileRead( ref Object address ) lee el valor del campo. Independientemente del número de procesadores o del estado de la caché del procesador, el valor es el más reciente escrito por cualquier procesador en la computadora. Este método tiene diferentes sobrecargas. Aquí se presentan algunas de ellas. |
22 | public static void VolatileWrite(
ref byte address,
byte value
) public static void VolatileWrite( ref double address, double value ) public static void VolatileWrite( ref int address, int value ) public static void VolatileWrite( ref Object address, Object value ) Escribe inmediatamente un valor en un campo para que sea visible para todos los procesadores en la computadora. Este método tiene diferentes sobrecargas. Aquí se presentan algunas de ellas. |
23 | public static bool Yield() que provoca que se llame a otro hilo que esté listo para ejecutarse en el procesador actual. El sistema operativo elige qué hilo ejecutar. |
Los hilos se crean extendiendo la clase Thread. La clase Thread extendida llama Start() métodos para comenzar la ejecución del hilo secundario.
A continuación, se muestra un programa que ilustra este concepto:
using System; using System.Threading; namespace MultithreadingApplication { class ThreadCreationProgram { public static void CallToChildThread() { Console.WriteLine("El subproceso Child comienza"); } static void Main(string[] args) { ThreadStart childref = new ThreadStart(CallToChildThread); Console.WriteLine("In Main: Creating the Child thread"); Thread childThread = new Thread(childref); childThread.Start(); Console.ReadKey(); } } }
Cuando el código anterior se compila y ejecuta, se producirá el siguiente resultado:
En Main: Creando el hilo hijo El hilo hijo comienza
La clase Thread ofrece varios métodos para gestionar hilos.
A continuación, se muestra un ejemplo de sleep() El uso del método, destinado a detener un hilo durante un tiempo específico.
using System; using System.Threading; namespace MultithreadingApplication { class ThreadCreationProgram { public static void CallToChildThread() { Console.WriteLine("El subproceso Child comienza"); // detener el hilo durante un tiempo específico. 5000 milisegundos int sleepfor = 5000; Console.WriteLine("Hilo secundario pausado durante {0} segundos", sleepfor / 1000); Thread.Sleep(sleepfor); Console.WriteLine("Hilo secundario se reanuda"); } static void Main(string[] args) { ThreadStart childref = new ThreadStart(CallToChildThread); Console.WriteLine("In Main: Creating the Child thread"); Thread childThread = new Thread(childref); childThread.Start(); Console.ReadKey(); } } }
Cuando el código anterior se compila y ejecuta, se producirá el siguiente resultado:
En Main: Creando el hilo hijo El hilo hijo comienza El subproceso Child se pausó por 5 segundos El subproceso Child se reanuda
Abort() método se utiliza para destruir el hilo.
mediante el lanzamiento threadabortexception detener el hilo en tiempo de ejecución. Esta excepción no puede ser capturada, si finally bloque, el control se enviará a finally bloque.
El siguiente programa ilustra esto:
using System; using System.Threading; namespace MultithreadingApplication { class ThreadCreationProgram { public static void CallToChildThread() { try { Console.WriteLine("El subproceso Child comienza"); // contar hasta 10 for (int counter = 0; counter <= 10; counter++) { Thread.Sleep(500); Console.WriteLine(counter); } Console.WriteLine("Subproceso Child completado"); } catch(ThreadAbortException e) { Console.WriteLine("Exception de Aborto de Thread"); } finally { Console.WriteLine("No se pudo capturar la Exception de Thread"); } } static void Main(string[] args) { ThreadStart childref = new ThreadStart(CallToChildThread); Console.WriteLine("In Main: Creating the Child thread"); Thread childThread = new Thread(childref); childThread.Start(); // Detener la línea principal por un tiempo Thread.Sleep(2000); // Ahora detiene la subproceso Console.WriteLine("In Main: Aborting the Child thread"); childThread.Abort(); Console.ReadKey(); } } }
Cuando el código anterior se compila y ejecuta, se producirá el siguiente resultado:
En Main: Creando el hilo hijo El hilo hijo comienza 0 1 2 En Main: Abortando el hilo hijo Excepción de aborto de hilo No se pudo capturar la excepción de hilo