目录
C++ 中的 <thread>
库提供了多线程编程的支持。它定义了 std::thread
类,用于创建和管理线程。
以下是 <thread>
库中一些常用的类和函数:
std::thread
:线程对象
可以通过它创建和管理线程。可以使用构造函数传递线程函数和参数来创建线程,并使用成员函数如 join()
、detach()
、joinable()
等管理线程的行为。
在使用std::thread船舰线程时,需要传入线程函数和其参数,
template< class Function, class... Args > explicit thread( Function&& f, Args&&... args );
其中,
Function
是线程函数的类型,Args
是线程函数的参数类型。#include <iostream> #include <thread> // 线程函数 void threadFunction(int arg1, const std::string& arg2) { std::cout << "Thread Function: " << arg1 << ", " << arg2 << std::endl; } int main() { int arg1 = 42; std::string arg2 = "Hello"; // 创建线程并传递参数 std::thread t(threadFunction, arg1, arg2); // 等待线程结束 t.join(); return 0; }
这里还可以使用lambda表达式或者绑定函数创建线程函数:
lambda表达式:
#include <iostream> #include <thread> int main() { int arg1 = 42; std::string arg2 = "Hello"; // 使用 Lambda 表达式创建线程函数 std::thread t([&arg1, &arg2]() { std::cout << "Thread Function: " << arg1 << ", " << arg2 << std::endl; }); // 等待线程结束 t.join(); return 0; }
bind绑定器:
#include <iostream> #include <thread> #include <functional> void threadFunction(int arg1, const std::string& arg2) { std::cout << "Thread Function: " << arg1 << ", " << arg2 << std::endl; } int main() { int arg1 = 42; std::string arg2 = "Hello"; // 使用 std::bind 创建线程函数 auto threadFunc = std::bind(threadFunction, arg1, arg2); std::thread t(threadFunc); // 等待线程结束 t.join(); return 0; }
join():
std::thread t(myFunction); // 创建线程对象并传递线程函数 // ... t.join(); // 等待线程执行完毕
用于等待线程的完成。调用
join()
会阻塞当前线程,直到被调用的线程执行完毕。确保主线程在子线程完成之前不会提前退出,从而避免多个线程同时运行导致的竞态条件不确定。
detach():
std::thread t(myFunction); // 创建线程对象并传递线程函数 // ... t.detach(); // 分离线程
用于将线程对象和底层线程分离,线程对象不再与线程关联,线程在后台继续运行,线程对象和线程不再关联。
线程在后台运行,会等待线程函数执行完毕。
joinable():
std::thread t(myFunction); // 创建线程对象并传递线程函数 // ... if (t.joinable()) { t.join(); // 加入线程 }
调用
t.joinable()
来检查线程对象是否可以被加入。如果返回值为true
,则可以安全地调用t.join()
来等待线程完成。如果返回值为false
,则说明线程对象已经被加入或分离,无法再次加入。
std::this_thread
命名空间:
提供了与当前线程相关的功能。包括 sleep_for()
、yield()
、get_id()
等函数,用于控制线程的休眠、让渡 CPU 和获取线程 ID 等操作。
sleep_for()
#include <thread> #include <chrono> // ... std::chrono::seconds duration(5); // 休眠5秒钟 std::this_thread::sleep_for(duration); // 当前线程休眠指定的时间段
sleep_for()
接受一个时间段作为参数,可以使用std::chrono
命名空间中的各种时间类型,如std::chrono::seconds
、std::chrono::milliseconds
、std::chrono::microseconds
等。可以根据实际需要选择合适的时间单位。
sleep_for()
的调用会阻塞当前线程,暂停执行,直到指定的时间段过去。在休眠期间,线程不会执行任何操作。一旦休眠时间结束,线程将恢复执行。
yield()
#include <thread> #include <iostream> // ... std::thread::yield(); // 提示线程调度器让出当前线程的执行时间片
yield()
的作用是在多线程环境中合理分配 CPU 时间,避免某个线程长时间独占 CPU 而导致其他线程无法获得执行机会。通过调用yield()
,我们可以主动放弃当前线程的执行权,提高系统的并发性和响应性。
get_id()
#include <thread> #include <iostream> // ... std::thread::id threadId = std::this_thread::get_id(); // 获取当前线程的唯一标识符 std::cout << "Thread ID: " << threadId << std::endl;
用于获取线程的唯一标识符。
get_id()
只能在已经创建的线程中使用,不能在主线程(main 函数所在的线程)中使用,因为主线程没有对应的std::thread
对象。
std::mutex
:互斥量
用于实现线程间的互斥操作。可以通过 std::lock_guard
或 std::unique_lock
等 RAII 类来管理互斥量的加锁和解锁。
std::condition_variable
:条件变量
用于实现线程间的同步和通信。通过 wait()
、notify_one()
、notify_all()
等函数来实现等待和唤醒线程的操作。
wait():
wait()
函数接受一个互斥量(std::unique_lock<std::mutex>
)和一个条件(lambda 表达式或可调用对象),当条件变量不满足条件时,线程将被阻塞,直到条件变量满足条件。
//wait 一直等 等到满足函数才停止
//wait_for + 持续等待的时间 等条件满足但是 设置最多等待时间 等十秒
//wait_until + 时间终止的点 等到下星期一
std::atomic
:原子类型
用于实现线程安全的操作。包括原子的读写操作和一些原子的计算操作,保证多线程环境下的数据一致性和原子性。