多线程是一种允许并行执行程序的两个或多个部分以最大程度地利用 CPU 的功能。此类程序的每个部分称为线程。因此,线程是进程中的轻量级进程。
C++11 中引入了多线程支持。在 C++11 之前,我们必须使用POSIX 线程或 库。虽然这个库完成了这项工作,但缺乏任何标准语言提供的功能集导致了严重的可移植性问题。C++ 11 废除了所有这些并给了我们std::thread。线程类和相关函数在头文件中定义。
句法:
std::thread thread_object(可调用);
std::thread是 C++ 中表示单个线程的线程类。要启动一个线程,我们只需创建一个新的线程对象并将要调用的执行代码(即可调用对象)传递到该对象的构造函数中。创建对象后,将启动一个新线程,该线程将执行 callable 中指定的代码。可调用对象可以是这三个中的任何一个
函数指针
函数对象
Lambda 表达式
定义可调用对象后,我们将其传递给构造函数。
使用函数指针启动线程
函数指针可以是传递给 std::thread 构造函数以初始化线程的可调用对象。以下代码片段演示了它是如何完成的。
例子:
C++
void foo(param)
{
Statements;
}
// The parameters to the function are put after the comma
std::thread thread_obj(foo, params);
使用 Lambda 表达式启动线程
std::thread 对象也可以使用 lambda 表达式作为可调用来启动。以下代码片段演示了这是如何完成的:
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);
使用函数对象启动线程
函数对象或函数也可用于在 C++ 中启动线程。以下代码片段演示了它是如何完成的:
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)
注意:我们总是将可调用的参数作为参数单独传递给线程构造函数。
等待线程完成
一旦线程启动,我们可能需要等待线程完成才能执行某些操作。例如,如果我们将初始化应用程序GUI的任务分配给一个线程,我们需要等待该线程完成以确保GUI已正确加载。
要等待线程,请使用std::thread::join()函数。该函数使当前线程等待,直到*this标识的线程执行完毕。
例如,要阻塞主线程直到线程 t1 完成,我们会这样做:
C++
int main()
{
// Start thread t1
std::thread t1(callable);
// Wait for t1 to finish
t1.join();
// t1 has finished do other stuff
Statements;
}
完整的多线程 C++ 程序
下面给出一个C++程序。它从主函数启动三个线程。每个线程都使用上面指定的可调用对象之一进行调用。
C++
// C++ 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";
}
};
// 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 < x; i++)
cout << "Thread using lambda"
" expression as callable\n";
};
// This thread is launched by using
// lambda 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;
}
输出(取决于机器)
线程 1、2 和 3 独立运行
使用函数指针作为可调用线程
使用函数指针作为可调用线程
使用函数指针作为可调用线程
使用函数对象作为可调用的线程
使用函数对象作为可调用的线程
使用函数对象作为可调用的线程
使用 lambda 表达式作为可调用线程
使用 lambda 表达式作为可调用线程
使用 lambda 表达式作为可调用线程
注意: 要编译支持 std::thread 的程序,请使用 g++ -std=c++11 -pthread。