Multihilo en C++

La compatibilidad con subprocesos múltiples se introdujo en C+11. Antes de C++ 11, teníamos que usar subprocesos POSIX o la biblioteca de subprocesos p en C . Si bien esta biblioteca hizo el trabajo, la falta de un conjunto de funciones proporcionado por un lenguaje estándar causó serios problemas de portabilidad. C++ 11 eliminó todo eso y nos dio std::thread . Las clases de subprocesos y las funciones relacionadas se definen en el archivo de encabezado del subproceso .

std::thread es la clase de hilo que representa un único hilo en C++. Para iniciar un subproceso, simplemente necesitamos crear un nuevo objeto de subproceso 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 inicia un nuevo hilo que ejecutará el código especificado en callable.

Un invocable puede ser cualquiera de los tres

  • Un puntero de función
  • Un objeto de función
  • Una expresión lambda
    • Después de definir callable, páselo al constructor.

      #include<thread>
      std::thread thread_object(callable)

      Lanzar hilo usando el puntero de función
      El siguiente fragmento de código demuestra cómo se hace esto

      void foo(param)
      {
          // Do something
      }
        
      // The parameters to the function are put after the comma
      std::thread thread_obj(foo, params);

      Lanzar hilo usando la expresión lambda

      El siguiente fragmento de código demuestra cómo se hace esto

      // Define a lamda expression
      auto f = [](params) {
          // Do Something
      };
        
      // Pass f and its parameters to thread 
      // object constructor as
      std::thread thread_object(f, params);

      También podemos pasar funciones lambda directamente al constructor.

      std::thread thread_object([](params) {
          // Do Something
      };, params);

      Lanzar hilos usando objetos de función

      El siguiente fragmento de código demuestra cómo se hace esto

      // Define the class of function object
      class fn_object_class {
          // Overload() operator
          void operator()(params)
          {
              // Do Something
          }
      }
        
      // Create thread object
      std::thread thread_object(fn_object_class(), params)

      Esperando a que terminen los hilos

      Una vez que se ha iniciado un hilo, es posible que tengamos que esperar a que finalice antes de que podamos tomar alguna medida. Por ejemplo, si asignamos la tarea de inicializar la GUI de una aplicación a un subproceso, debemos esperar a que finalice el subproceso para asegurarnos de que la GUI se haya cargado correctamente.

      Para esperar un hilo, use la función std::thread::join() . Esta función hace que el subproceso actual espere hasta que el subproceso identificado por *this haya terminado de ejecutarse.
      Por ejemplo, para bloquear el subproceso principal hasta que finalice el subproceso t1, haríamos

      int main()
      {
          // Start thread t1
          std::thread t1(callable);
        
          // Wait for t1 to finish
          t1.join();
        
          // t1 has finished do other stuff
        
          ...
      }

      Un programa completo en C++

      A continuación se proporciona un programa en C++. Lanza tres hilos desde la función principal. Cada subproceso se llama utilizando uno de los objetos invocables especificados anteriormente.

      // CPP program to demonstrate multithreading
      // using three different callables.
      #include <iostream>
      #include <thread>
      using namespace std;
        
      // A dummy function
      void foo(int Z)
      {
          for (int i = 0; i < Z; i++) {
              cout << "Thread using function"
                     " pointer as callable\n";
          }
      }
        
      // A callable object
      class thread_obj {
      public:
          void operator()(int x)
          {
              for (int i = 0; i < x; i++)
                  cout << "Thread using function"
                        " object as  callable\n";
          }
      };
        
      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 < x; i++)
                  cout << "Thread using lambda"
                   " expression as callable\n";
          };
        
          // This thread is launched by using 
          // lamda expression as callable
          thread th3(f, 3);
        
          // 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();
        
          return 0;
      }

      Salida (dependiente de la máquina)

Threads 1 and 2 and 3 operating independently                                                       
Thread using function pointer as callable                                                           
Thread using lambda expression as callable                                                          
Thread using function pointer as callable                                                           
Thread using lambda expression as callable                                                          
Thread using function object as  callable                                                          
Thread using lambda expression as callable                                                          
Thread using function pointer as callable                                                          
Thread using function object as  callable                                                           
Thread using function object as  callable

Nota:
Para compilar programas con std::thread support use

g++ -std=c++11 -pthread

Referencias
cppreference – hilo

Publicación traducida automáticamente

Artículo escrito por Sayan Mahapatra y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *