0
点赞
收藏
分享

微信扫一扫

【2024高教社杯全国大学生数学建模竞赛】B题模型建立求解

小猪肥 2024-09-06 阅读 30
c++

目录

 A、线程/多线程基础

一、C++11 创建线程的几种方式

1.1 使用函数指针

1.2 使用 lambda 表达式

1.3 使用成员函数

1.4 使用可调用对象 (Functor)

二、定义一个线程类

三、join() 与 detach() 的详细用法及区别

3.1 join() 的用法

3.2 detach() 的用法

3.3 join() 与 detach() 的区别总结

四、std::this_thread

4.1、主要功能

std::this_thread::get_id()

std::this_thread::yield()

std::this_thread::sleep_for()

std::this_thread::sleep_until()

4.2、各方法的用法及适用场景

1. std::this_thread::get_id()

2. std::this_thread::yield()

3. std::this_thread::sleep_for()

4. std::this_thread::sleep_until()

4.3、std::this_thread::sleep_for 与 std::this_thread::sleep_until 的区别

注:sleep_for 与 sleep_until 对比示例

五、std::mutex 详解

主要功能

使用场景

代码示例

1. 基本使用 std::mutex

2. 使用 try_lock()

3. 使用 std::lock_guard 简化互斥锁管理

4. 使用 std::scoped_lock 同时锁定多个互斥量

重要注意事项

总结

六、std::unique_lock

主要功能:

构造函数与锁定策略

使用示例

1. 基本使用:自动锁定与解锁

2. 手动锁定与解锁

3. 使用 try_lock 尝试锁定

4. 使用 adopt_lock 接管已经锁定的互斥量

std::unique_lock 与 std::lock_guard 的区别

总结

七、std::condition_variable::wait

std::condition_variable::wait 的原理

wait() 的使用场景

代码示例

1. 基本使用 wait() 和 notify_one()

2. 使用 notify_all() 唤醒所有等待线程

3. 防止虚假唤醒

4. wait_for() 和 wait_until()

4.1 使用 wait_for() 超时等待

4.2 使用 wait_until() 等待到指定时间点

总结

B、实现多线程以及示例


 A、线程/多线程基础

一、C++11 创建线程的几种方式

1.1 使用函数指针
#include <iostream>
#include <thread>

void threadFunction(int x) {
std::cout << "Thread function called with value: " << x << std::endl;
}

int main() {
std::thread t(threadFunction, 10);
t.join(); // 等待线程执行完毕
return 0;
}
1.2 使用 lambda 表达式
#include <iostream>
#include <thread>

int main() {
std::thread t([](int x) {
std::cout << "Lambda thread called with value: " << x << std::endl;
}, 20)
;

t.join(); // 等待线程执行完毕
return 0;
}
1.3 使用成员函数
#include <iostream>
#include <thread>

class MyClass {
public:
void memberFunction(int x) {
std::cout << "Member function called with value: " << x << std::endl;
}
};

int main() {
MyClass obj;
std::thread t(&MyClass::memberFunction,
t.join(); // 等待线程执行完毕
return 0;
}
1.4 使用可调用对象 (Functor)
#include <iostream>
#include <thread>

class Functor {
public:
void operator()(int x) {
std::cout << "Functor called with value: " << x << std::endl;
}
};

int main() {
Functor functor;
std::thread t(functor, 40);
t.join(); // 等待线程执行完毕
return 0;
}

二、定义一个线程类

#include <iostream>
#include <thread>

class ThreadClass {
private:
std::thread t;

public:
// 构造函数,接受函数和参数来启动线程
template <typename Callable, typename... Args>
explicit ThreadClass(Callable&& func, Args&&... args) {
t = std::thread(std::forward<Callable>(func), std::forward<Args>(args)...);
}

// 加入线程(等待线程完成)
void join() {
if (t.joinable()) {
t.join();
}
}

// 分离线程(让线程独立运行)
void detach() {
if (t.joinable()) {
t.detach();
}
}

// 析构函数,确保线程对象在销毁前已被处理
~ThreadClass() {
if (t.joinable()) {
t.join(); // 通常在析构时,选择 join 或 detach 来处理未处理的线程
}
}
};

void threadFunction(int x) {
std::cout << "Thread function running with value: " << x << std::endl;
}

int main() {
// 使用类来管理线程
ThreadClass threadObj(threadFunction, 50);
threadObj.join(); // 等待线程完成
return 0;
}

三、join()detach() 的详细用法及区别

3.1 join() 的用法
#include <iostream>
#include <thread>

void task() {
std::cout << "Task is running in thread." << std::endl;
}

int main() {
std::thread t(task);

// 主线程等待子线程完成
std::cout << "Waiting for thread to finish..." << std::endl;
t.join(); // 阻塞,直到子线程完成
std::cout << "Thread has finished." << std::endl;

return 0;
}

解释

3.2 detach() 的用法

示例:

#include <iostream>
#include <thread>
#include <chrono>

void task() {
std::cout << "Detached thread is running." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟耗时操作
std::cout << "Detached thread finished." << std::endl;
}

int main() {
std::thread t(task);

// 分离线程,允许其在后台运行
t.detach();

// 主线程不等待子线程完成,继续执行
std::cout << "Main thread is not waiting for detached thread." << std::endl;

// 模拟主线程的其他操作
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Main thread finished." << std::endl;

return 0;
}

解释

3.3 join()detach() 的区别总结

四、std::this_thread

4.1、主要功能
4.2、各方法的用法及适用场景

总结

std::this_thread 提供了一个简单而强大的接口,用于控制当前线程的行为,包括:

  • 获取当前线程的 ID:有助于在调试和日志记录中识别不同线程。
  • 让出线程的执行权:通过 yield() 提高 CPU 使用效率,允许系统调度其他线程。
  • 让线程休眠:可以使用 sleep_forsleep_until 暂时暂停线程的执行,应用场景包括定时任务、延迟执行等。

这些工具使得 C++11 开始的多线程编程变得更加灵活和易于控制。

五、std::mutex 详解

std::mutex 是 C++11 引入的一种线程同步机制,用于在多线程环境下防止数据竞争(race condition)。在多线程程序中,如果多个线程同时访问并修改同一个共享数据,会导致数据竞争问题,造成不可预知的错误。std::mutex(互斥量)提供了一种机制,确保每次只有一个线程能够访问共享资源,其他线程必须等待,直到前一个线程释放互斥量。

主要功能
  1. lock():锁定互斥量。如果互斥量已经被其他线程锁定,则调用 lock() 的线程将会阻塞,直到该互斥量被解锁。
  2. unlock():解锁互斥量,允许其他线程锁定它。
  3. try_lock():尝试锁定互斥量。如果互斥量已被其他线程锁定,则返回 false,否则锁定并返回 true
使用场景
代码示例
1. 基本使用 std::mutex

这是一个简单的例子,展示了如何使用 std::mutex 来保护共享数据(计数器),防止多个线程同时修改它。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx; // 全局互斥量,用于同步对共享数据的访问
int counter = 0; // 共享资源

void increaseCounter() {
for (int i = 0; i < 10000; ++i) {
mtx.lock(); // 锁定互斥量,进入临界区
++counter; // 对共享数据进行操作
mtx.unlock(); // 解锁互斥量,离开临界区
}
}

int main() {
// 创建两个线程,执行 increaseCounter 函数
std::thread t1(increaseCounter);
std::thread t2(increaseCounter);

// 等待两个线程完成
t1.join();
t2.join();

// 输出最终的计数器值
std::cout << "Final counter value: " << counter << std::endl;
return 0;
}

解释

  • 互斥量 mtx:在每个线程访问共享资源之前使用 lock() 来锁定互斥量,保证在任何时候只有一个线程可以修改 counter 变量。
  • 临界区:临界区是指 mtx.lock()mtx.unlock() 之间的代码区域,即对共享资源的访问部分。
  • 线程安全:在互斥量的保护下,两个线程不会同时修改 counter,因此保证了线程安全。

输出示例

Final counter value: 20000

如果没有使用 std::mutex,两个线程可能同时访问并修改 counter,导致最后输出的值小于预期的 20000,因为多个线程可能在同一时刻操作同一内存位置,发生了数据竞争。

2. 使用 try_lock()

try_lock()std::mutex 提供的另一个方法,它不会阻塞线程。如果互斥量已经被锁定,try_lock() 会立即返回 false,而不是阻塞等待。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx; // 全局互斥量

void printMessage(const std::string& msg) {
if (mtx.try_lock()) { // 尝试获取锁,如果成功则执行
std::cout << msg << std::endl;
mtx.unlock(); // 解锁
} else {
std::cout << "Lock busy, couldn't print: " << msg << std::endl;
}
}

int main() {
std::thread t1(printMessage, "Hello from Thread 1");
std::thread t2(printMessage, "Hello from Thread 2");

t1.join();
t2.join();

return 0;
}

解释

  • try_lock() 方法尝试锁定互斥量。如果成功获取锁,它就进入临界区执行输出操作;如果未能获取锁,说明其他线程已锁定了互斥量,则输出 "Lock busy"。

输出示例

Hello from Thread 1
Lock busy, couldn't print: Hello from Thread 2
3. 使用 std::lock_guard 简化互斥锁管理

C++11 提供了 std::lock_guard,它是一个 RAII 风格的锁管理器,在作用域结束时自动释放锁,避免了手动 lock()unlock() 可能引发的错误。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx; // 全局互斥量
int counter = 0; // 共享资源

void increaseCounter() {
for (int i = 0; i < 10000; ++i) {
std::lock_guard<std::mutex> lock(mtx); // 自动锁定互斥量,作用域结束时自动解锁
++counter;
}
}

int main() {
std::thread t1(increaseCounter);
std::thread t2(increaseCounter);

t1.join();
t2.join();

std::cout << "Final counter value: " << counter << std::endl;
return 0;
}

解释

  • std::lock_guard 是一个模板类,管理互斥锁的生命周期。它在构造时自动锁定互斥量,在作用域结束时(例如函数返回或异常抛出时)自动解锁,避免了忘记解锁或出现死锁的情况。

输出示例

Final counter value: 20000
4. 使用 std::scoped_lock 同时锁定多个互斥量

C++17 引入了 std::scoped_lock,它不仅可以同时锁定多个互斥量,还能防止死锁。std::scoped_lockstd::lock_guard 的改进版,特别适用于需要同时锁定多个资源的场景。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx1, mtx2; // 两个互斥量

void task1() {
std::scoped_lock lock(mtx1, mtx2); // 同时锁定 mtx1 和 mtx2
std::cout << "Task 1 has locked both mutexes." << std::endl;
}

void task2() {
std::scoped_lock lock(mtx1, mtx2); // 同时锁定 mtx1 和 mtx2
std::cout << "Task 2 has locked both mutexes." << std::endl;
}

int main() {
std::thread t1(task1);
std::thread t2(task2);

t1.join();
t2.join();

return 0;
}

解释

  • std::scoped_lock 同时锁定多个互斥量,并且能避免死锁。它会确保在解锁时,以相反顺序解锁,从而避免了交叉锁定不同互斥量时可能发生的死锁问题。

输出示例

Task 1 has locked both mutexes.
Task 2 has locked both mutexes.
重要注意事项
  1. 锁的生命周期:互斥量应该在所有访问共享资源的线程中共享。一个线程加锁后,其他线程必须等待该锁被解锁才能继续执行。
  2. 防止死锁:在多个互斥量之间锁定时(如同时访问多个资源),应小心防止死锁。死锁发生在多个线程相互等待其他线程释放锁的情况下。使用 std::scoped_lock 可以简化锁定多个资源时的死锁管理。
  3. lock_guardscoped_lock 的推荐使用lock_guardscoped_lock 是 RAII 风格的锁管理工具,推荐使用这些工具来管理锁的生命周期,避免手动 lock()unlock() 可能引发的错误。
总结

std::mutex 是 C++11 提供的基本线程同步工具,用于解决多线程编程中的数据竞争问题。通过互斥量可以确保同一时刻只有一个线程能够访问共享资源,防止多个线程同时修改数据而导致不可预测的行为。结合 std::lock_guardstd::scoped_lock,可以更简便地管理锁的生命周期,确保代码更加安全和高效。

六、std::unique_lock

  • 可以延迟锁定互斥量(懒惰锁定)。
  • 可以在需要时手动解锁和重新锁定。
  • 可以使用 std::try_lockstd::defer_lockstd::adopt_lock 等高级锁定策略。
主要功能:
使用示例
1. 基本使用:自动锁定与解锁

std::unique_lock 可以像 std::lock_guard 一样,在构造时自动锁定互斥量,并在析构时自动解锁。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx; // 全局互斥量
int counter = 0; // 共享资源

void increaseCounter() {
for (int i = 0; i < 10000; ++i) {
std::unique_lock<std::mutex> lock(mtx); // 自动锁定互斥量
++counter; // 临界区
// lock 会在作用域结束时自动解锁
}
}

int main() {
std::thread t1(increaseCounter);
std::thread t2(increaseCounter);

t1.join();
t2.join();

std::cout << "Final counter value: " << counter << std::endl;
return 0;
}

解释

  • std::unique_lock 的构造函数会立即锁定互斥量 mtx,并且当 lock 作用域结束时,它会自动解锁。这种机制避免了手动调用 unlock() 的必要。
2. 手动锁定与解锁

你可以通过 std::unique_lock 对互斥量进行手动锁定和解锁操作,控制更为灵活。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void task() {
std::unique_lock<std::mutex> lock(mtx, std::defer_lock); // 延迟锁定互斥量
std::cout << "Before locking" << std::endl;

lock.lock(); // 手动锁定互斥量
std::cout << "Locked and working..." << std::endl;

lock.unlock(); // 手动解锁
std::cout << "Unlocked" << std::endl;
}

int main() {
std::thread t(task);
t.join();
return 0;
}

解释

  • 这里使用了 std::defer_lockstd::unique_lock 在构造时不会自动锁定互斥量。随后,我们手动调用了 lock()unlock() 来控制互斥量的锁定和解锁过程。
3. 使用 try_lock 尝试锁定

std::unique_lock 还可以用于尝试锁定互斥量,而不阻塞线程。如果锁定失败,线程可以继续执行其他任务。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void task() {
std::unique_lock<std::mutex> lock(mtx, std::try_to_lock); // 尝试锁定互斥量
if (lock.owns_lock()) {
std::cout << "Lock acquired, working..." << std::endl;
} else {
std::cout << "Couldn't acquire lock, doing other work..." << std::endl;
}
}

int main() {
std::thread t1(task);
std::thread t2(task);

t1.join();
t2.join();
return 0;
}

解释

  • 通过 std::try_to_lock,线程会尝试锁定互斥量。如果无法锁定,程序可以继续执行其他任务,而不是阻塞等待锁的释放。
  • owns_lock() 可以检查 std::unique_lock 是否成功锁定互斥量。
4. 使用 adopt_lock 接管已经锁定的互斥量

如果你手动锁定了互斥量,但希望将它交给 std::unique_lock 来管理,可以使用 std::adopt_lock。这会告诉 std::unique_lock,互斥量已经被锁定,不再需要再次锁定。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void task() {
mtx.lock(); // 手动锁定互斥量
std::unique_lock<std::mutex> lock(mtx, std::adopt_lock); // 接管锁
std::cout << "Lock adopted, working..." << std::endl;
// lock 会在作用域结束时自动解锁
}

int main() {
std::thread t(task);
t.join();
return 0;
}
std::unique_lockstd::lock_guard 的区别
  1. 灵活性

    • std::lock_guard 在构造时立即锁定互斥量,并在销毁时自动解锁。它适合用于简单的锁管理。
    • std::unique_lock 提供了更多灵活的功能,如延迟锁定、尝试锁定、手动解锁等。它适用于需要复杂锁定逻辑的场景。
  2. 锁的控制

    • std::lock_guard 不允许手动解锁,只能在作用域结束时解锁。
    • std::unique_lock 允许在代码中手动调用 unlock(),并且可以手动重新锁定。
  3. 性能

    • 由于 std::lock_guard 更简单,通常它的性能要比 std::unique_lock 稍高一些。但如果你的程序不需要 std::unique_lock 的灵活性,优先使用 std::lock_guard 会更高效。
总结

std::unique_lock 是一个灵活的锁管理工具,适合处理复杂的线程同步场景。它与 std::lock_guard 的区别在于其灵活的控制能力:支持延迟锁定、手动解锁、尝试锁定等操作。此外,std::unique_lock 可以使用 std::defer_lockstd::try_to_lockstd::adopt_lock 等锁定策略,适用于需要更精细控制的场景。在简单的锁定场景中,std::lock_guard 更适合,而 std::unique_lock 则适用于需要更多灵活性的场景。

七、std::condition_variable::wait

是 C++11 中引入的一个机制,用于在线程同步时协调多个线程之间的执行。它与 std::mutexstd::unique_lock 配合使用,用于阻塞线程直到特定条件满足。

std::condition_variable::wait 的原理

  1. 互斥锁wait() 必须与一个互斥锁(std::unique_lock)一起使用。它在调用 wait() 时会自动释放锁,进入等待状态,并在被通知时重新获取锁。
  2. 条件变量wait() 用于阻塞线程,直到另一个线程通过条件变量调用 notify_one()notify_all() 来通知等待线程可以继续执行。
  3. 通知机制
    • notify_one():唤醒一个等待的线程。
    • notify_all():唤醒所有等待的线程。

wait() 的使用场景

典型的 wait() 使用场景是生产者-消费者问题。在这种情况下,消费者等待生产者生成数据,而生产者在生成数据后通知消费者继续处理。

代码示例

1. 基本使用 wait()notify_one()

这是一个简单的示例,其中一个线程等待某个条件满足,而另一个线程在一定时间后设置条件并通知等待的线程继续执行。

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex mtx; // 互斥锁
std::condition_variable cv; // 条件变量
bool ready = false; // 条件标志

void waitForWork() {
std::unique_lock<std::mutex> lock(mtx); // 获取锁
std::cout << "Waiting for work to be ready...\n";

// 当 ready 为 false 时,线程进入等待状态,锁被自动释放
cv.wait(lock, [] { return ready; });

// 当 ready 为 true 时,wait 结束,线程重新获取锁
std::cout << "Work is ready, proceeding...\n";
}

void prepareWork() {
std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟工作准备
{
std::lock_guard<std::mutex> lock(mtx); // 获取锁并设置条件
ready = true;
std::cout << "Work is prepared, notifying worker...\n";
}
cv.notify_one(); // 通知等待线程可以继续执行
}

int main() {
std::thread worker(waitForWork); // 创建等待线程
std::thread preparer(prepareWork); // 创建准备线程

worker.join();
preparer.join();

return 0;
}

解释

  • wait():在 waitForWork() 函数中,调用 cv.wait(lock, [] { return ready; }),它将当前线程阻塞,直到 ready 变为 truewait() 在等待期间自动释放锁,避免其他线程无法获取锁。
  • notify_one():在 prepareWork() 函数中,调用 cv.notify_one() 通知等待的线程(waitForWork)可以继续执行。
  • 锁的管理wait()notify_one() 都需要与互斥锁配合使用,以保证线程之间的同步。

输出示例

Waiting for work to be ready...
Work is prepared, notifying worker...
Work is ready, proceeding...
2. 使用 notify_all() 唤醒所有等待线程

notify_all() 可以唤醒所有因条件不满足而阻塞的线程。这对于多个线程等待同一个条件的场景非常有用。

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void worker(int id) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return ready; }); // 所有线程都等待 ready 为 true
std::cout << "Worker " << id << " is proceeding.\n";
}

void prepareWork() {
std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟工作准备
{
std::lock_guard<std::mutex> lock(mtx);
ready = true;
std::cout << "Work is ready, notifying all workers...\n";
}
cv.notify_all(); // 通知所有等待的线程
}

int main() {
std::vector<std::thread> workers;

// 创建多个线程
for (int i = 1; i <= 5; ++i) {
workers.emplace_back(worker, i);
}

std::thread preparer(prepareWork); // 创建准备线程

// 等待所有线程完成
for (auto& t : workers) {
t.join();
}
preparer.join();

return 0;
}

解释

  • notify_all()notify_all() 会唤醒所有等待的线程,这里唤醒了 5 个 worker 线程。
  • 多线程等待:所有 worker 线程都会在 cv.wait() 中等待,直到 ready 变为 true 并且收到通知。

输出示例

Work is ready, notifying all workers...
Worker 1 is proceeding.
Worker 2 is proceeding.
Worker 3 is proceeding.
Worker 4 is proceeding.
Worker 5 is proceeding.
3. 防止虚假唤醒

虚假唤醒(spurious wakeups)是指线程在没有被条件变量显式唤醒的情况下,也可能会被唤醒。这是操作系统的特性,因此我们在使用 wait() 时应该总是配合条件判断来避免这种情况。

为了避免虚假唤醒,C++ 中的 wait() 提供了一种安全的模式,即使用条件判断的 lambda 表达式来确保条件满足时才继续执行。

cv.wait(lock, [] { return ready; });

这个版本的 wait() 会在 readyfalse 时继续阻塞线程,直到条件真正满足。

4. wait_for()wait_until()

除了 wait() 之外,C++11 还提供了 wait_for()wait_until() 方法,允许我们指定等待的时间。如果在指定的时间内条件未满足,线程会超时并继续执行。

  • wait_for():阻塞线程一段时间,超时后线程自动返回。
  • wait_until():阻塞线程直到某个时间点,超时后线程自动返回。
4.1 使用 wait_for() 超时等待
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void worker() {
std::unique_lock<std::mutex> lock(mtx);
if (cv.wait_for(lock, std::chrono::seconds(3), [] { return ready; })) {
std::cout << "Work is ready, proceeding...\n";
} else {
std::cout << "Timeout, work is not ready.\n";
}
}

void prepareWork() {
std::this_thread::sleep_for(std::chrono::seconds(5)); // 模拟准备时间
{
std::lock_guard<std::mutex> lock(mtx);
ready = true;
std::cout << "Work is prepared, notifying worker...\n";
}
cv.notify_one();
}

int main() {
std::thread t1(worker);
std::thread t2(prepareWork);

t1.join();
t2.join();

return 0;
}

解释

  • wait_for():等待 3 秒,如果 ready 在 3 秒内没有变为 true,线程会超时并继续执行。
  • 超时处理:如果超过等待时间,线程会输出 "Timeout, work is not ready."。

输出示例

Timeout, work is not ready.
Work is prepared, notifying worker...
4.2 使用 wait_until() 等待到指定时间点
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void worker() {
auto timeout = std::chrono::system_clock::now() + std::chrono::seconds(3);
std::unique_lock<std::mutex> lock(mtx);
if (cv.wait_until(lock, timeout, [] { return ready; })) {
std::cout << "Work is ready, proceeding...\n";
} else {
std::cout << "Timeout, work is not ready.\n";
}
}

void prepareWork() {
std::this_thread::sleep_for(std::chrono::seconds(5)); // 模拟准备时间
{
std::lock_guard<std::mutex> lock(mtx);
ready = true;
std::cout << "Work is prepared, notifying worker...\n";
}
cv.notify_one();
}

int main() {
std::thread t1(worker);
std::thread t2(prepareWork);

t1.join();
t2.join();

return 0;
}

解释

  • wait_until():等待到指定时间点,如果在这个时间点前 ready 变为 true,线程会继续执行;否则超时。

输出示例

Timeout, work is not ready.
Work is prepared, notifying worker...

总结

  • std::condition_variable::wait 用于协调线程之间的同步,它可以让一个线程在等待某个条件满足时进入等待状态,并通过条件变量的 notify_one()notify_all() 来唤醒线程。
  • wait() 需要与 std::mutexstd::unique_lock 配合使用,以保证线程在等待期间不会造成数据竞争。
  • wait_for()wait_until() 提供了超时等待机制,允许线程在指定的时间内等待条件满足,否则超时返回。

B、实现多线程以及示例

举报

相关推荐

0 条评论