📜  C++中的多线程

📅  最后修改于: 2021-05-30 15:52:15             🧑  作者: Mango

C + 11中引入了多线程支持。在C++ 11之前,我们必须在C中使用POSIX线程或p线程库。尽管该库完成了工作,但缺少任何提供功能集的标准语言都会导致严重的可移植性问题。 C++ 11消除了所有这些,并给了我们std :: thread 。线程类和相关函数在线程头文件中定义。

std :: thread是表示C++中单个线程的线程类。要启动线程,我们只需要创建一个新的线程对象并将要调用的执行代码(即可调用对象)传递到该对象的构造函数中即可。创建对象后,将启动一个新线程,该线程将执行callable中指定的代码。

可调用对象可以是三个

  • 函数指针
  • 函数对象
  • Lambda表达式

      定义callable之后,将其传递给构造函数。

      #include
      std::thread thread_object(callable)
      

      使用函数指针启动线程
      以下代码段演示了如何完成此操作

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

      使用Lambda表达式启动线程

      以下代码段演示了如何完成此操作

      // 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);
      

      我们还可以将lambda函数直接传递给构造函数。

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

      使用函数对象启动线程

      以下代码段演示了如何完成此操作

      // 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_class_object(), params)
      

      等待线程完成

      线程启动后,我们可能需要等待线程完成才能采取一些措施。例如,如果我们将初始化应用程序GUI的任务分配给线程,则需要等待线程完成以确保GUI正确加载。

      要等待线程,请使用std :: thread :: join()函数。该函数使当前线程等待,直到由* this标识的线程完成执行。
      例如,要阻塞主线程直到线程t1完成,我们将执行

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

      完整的C++程序

      下面给出了一个C++程序。它从main函数启动三个线程。使用上面指定的可调用对象之一调用每个线程。

      // CPP 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 < 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;
      }
      

      输出(取决于机器)

      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
      

      笔记:
      要使用std :: thread支持来编译程序,请使用

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

      参考
      cppreference –线程

      要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”