Multithreading es una característica que permite la ejecución simultánea de dos o más partes de un programa para una utilización máxima de la CPU. Cada parte de dicho programa se llama hilo. Entonces, los subprocesos son procesos livianos dentro de un proceso.
llave ins
La compatibilidad con subprocesos múltiples se introdujo en C++ 11. Antes de C++ 11, teníamos que usar Hilos o biblioteca POSIX . Si bien esta biblioteca hizo el trabajo, la falta de un conjunto de funciones estándar proporcionadas en un idioma causó serios problemas de portabilidad. C++ 11 eliminó todo eso y nos dio std::hilo . Las clases de subprocesos y funciones relacionadas se definen en el archivo de cabecera.
Sintaxis:
std::thread thread_object (callable);>
std::hilo es la clase de subproceso que representa un único subproceso en C++. Para iniciar un hilo, simplemente necesitamos crear un nuevo objeto de hilo y pasar el código de ejecución que se llamará (es decir, un objeto invocable) al constructor del objeto. Una vez que se crea el objeto, se lanza un nuevo hilo que ejecutará el código especificado en invocable. Un invocable puede ser cualquiera de los cinco:
- Un puntero de función
- Una expresión lambda
- Un objeto de función
- Función de miembro no estático
- Función de miembro estático
Después de definir el invocable, lo pasamos al constructor.
Lanzar hilo usando el puntero de función
Un puntero de función puede ser un objeto invocable para pasar al constructor std::thread para inicializar un hilo. El siguiente fragmento de código demuestra cómo se hace.
Ejemplo:
C++
void> foo(param)> {> >Statements;> }> // The parameters to the function are put after the comma> std::>thread> thread_obj(foo, params);> |
>
>
Lanzamiento de hilo usando la expresión Lambda
El objeto std::thread también se puede iniciar utilizando una expresión lambda como invocable. El siguiente fragmento de código demuestra cómo se hace esto:
Ejemplo:
saltar lista
C++
// Define a lambda expression> auto> f = [](params)> {> >Statements;> };> // Pass f and its parameters to thread> // object constructor as> std::>thread> thread_object(f, params);> |
>
>
Lanzar hilo usando objetos de función
Los objetos de función o funtores también se pueden utilizar para iniciar un hilo en C++. El siguiente fragmento de código demuestra cómo se hace:
Ejemplo:
C++
// Define the class of function object> class> fn_object_class {> >// Overload () operator> >void> operator()(params)> >{> >Statements;> >}> }> // Create thread object> std::>thread> thread_object(fn_object_class(), params)> |
creación de instancias en java
>
>
Nota : Siempre pasamos los parámetros del invocable por separado como argumentos al constructor del hilo.
Lanzar hilo utilizando una función de miembro no estática
También podemos iniciar el hilo usando la función miembro no estática de una clase. El siguiente fragmento muestra cómo hacerlo.
C++
// defining clasc> class> Base {> public>:> >// non-static member function> >void> foo(param) { Statements; }> }> // object of Base Class> Base b;> // first parameter is the reference to the functionn> // and second paramter is reference of the object> // at last we have arguments> std::>thread> thread_obj(&Base::foo, &b, params);> |
>
>
Lanzar hilo usando la función de miembro estático
También podemos iniciar los hilos utilizando funciones miembro estáticas.
C++
// defining class> class> Base {> public>:> >// static member function> >static> void> foo(param) { Statements; }> }> // object of Base Class> Base b;> // first parameter is the reference to the function> // and rest are arguments> std::>thread> thread_obj(&Base::foo, params);> |
>
tipo de retorno en java
>
Esperando a que terminen los hilos
Una vez que un hilo ha comenzado, es posible que tengamos que esperar a que finalice antes de poder tomar alguna medida. Por ejemplo, si asignamos la tarea de inicializar la GUI de una aplicación a un hilo, debemos esperar a que finalice el hilo para asegurarnos de que la GUI se haya cargado correctamente.
Para esperar un hilo, use el std::hilo::unirse() función. Esta función hace que el hilo actual espere hasta que el hilo identificado por *este ha terminado de ejecutarse.
Por ejemplo, para bloquear el hilo principal hasta que el hilo t1 haya terminado, haríamos:
C++
int> main()> {> >// Start thread t1> >std::>thread> t1(callable);> >// Wait for t1 to finish> >t1.join();> >// t1 has finished do other stuff> >Statements;> }> |
>
>
Un programa completo en C++ para subprocesos múltiples
A continuación se proporciona un programa en C++. Lanza tres hilos desde la función principal. Cada hilo se llama utilizando uno de los objetos invocables especificados anteriormente.
C++
cadena comparable
// C++ program to demonstrate> // multithreading using three> // different callables.> #include> #include> using> namespace> std;> // A dummy function> void> foo(>int> Z)> {> >for> (>int> i = 0; i cout << 'Thread using function' ' pointer as callable
'; } } // A callable object class thread_obj { public: void operator()(int x) { for (int i = 0; i cout << 'Thread using function' ' object as callable
'; } }; // class definition class Base { public: // non-static member function void foo() { cout << 'Thread using non-static member function ' 'as callable' << endl; } // static member function static void foo1() { cout << 'Thread using static member function as ' 'callable' << endl; } }; // Driver code int main() { cout << 'Threads 1 and 2 and 3 ' 'operating independently' << endl; // This thread is launched by using // function pointer as callable thread th1(foo, 3); // This thread is launched by using // function object as callable thread th2(thread_obj(), 3); // Define a Lambda Expression auto f = [](int x) { for (int i = 0; i cout << 'Thread using lambda' ' expression as callable
'; }; // This thread is launched by using // lambda expression as callable thread th3(f, 3); // object of Base Class Base b; thread th4(&Base::foo, &b); thread th5(&Base::foo1); // Wait for the threads to finish // Wait for thread t1 to finish th1.join(); // Wait for thread t2 to finish th2.join(); // Wait for thread t3 to finish th3.join(); // Wait for thread t4 to finish th4.join(); // Wait for thread t5 to finish th5.join(); return 0; }> |
>
>
Salida (dependiente de la máquina)
Threads 1 and 2 and 3 operating independently Thread using function pointer as callable Thread using function pointer as callable Thread using function pointer as callable Thread using non-static member function as callable Thread using function object as callable Thread using function object as callable Thread using function object as callable Thread using lambda expression as callable Thread using lambda expression as callable Thread using lambda expression as callable Thread using static member function as callable>
Nota: Para compilar programas con soporte std::thread use g++ -std=c++11 -pthread.