本文共 3269 字,大约阅读时间需要 10 分钟。
在多线程编程中,原子操作是保证在多个线程之间保持一致性和正确性的关键。C++中的std::atomic提供了一种轻量级的原子操作机制,适用于处理不可线性化的变量操作。以下是关于std::atomic的一些关键点:
原子操作的支持操作:
std::atomic支持以下操作:++
、--
、+=
、=
、|=
和^=
。这些操作在多线程环境下保证原子性,防止数据竞争和舍去。例如,my_count += 1
会比 my_count = my_count + 1
更安全,因为前者不会在操作过程中被打断。原子操作的实现方式:
可以通过std::atomic<int>
类来封装整数类型的变量,像操作普通变量一样使用。例如:#include#include #include int my_count{ 0 }; // 使用std::atomic 封装int变量void my_thread() { for (int i = 0; i < 1000000; ++i) { my_count += 1; // 原子操作,保证线程安全 }}int main() { std::thread threadObj1(my_thread); std::thread threadObj2(my_thread); threadObj1.join(); threadObj2.join(); std::cout << "两个线程执行完毕,最终 my_count的值是" << my_count << std::endl; return 0;}
通过上述代码可以看到,多个线程同时对my_count进行操作时,结果仍然是正确的。
注意事项:
如果使用my_count = my_count + 1
,则不一定保证原子性,因为在某些情况下可能会导致不可见的读写冲突。因此,建议在多线程环境下始终使用支持的原子操作符。std::async和std::thread都是用于在C++中创建和管理线程的工具,但它们在工作机制和使用方式上有显著的不同。以下是详细对比:
std::async接受一个入口函数作为参数,可以通过以下方式使用:
#include#include #include using namespace std;future result = async(mythread);// 或者future result = async(std::launch::async, mythread);
参数说明:
std::launch::deferred
:延迟调用,异步任务不会立即执行。std::launch::async
:强制在新线程上执行异步任务。std::launch::async | std::launch::deferred
,系统会自行选择策略。作用:
std::async创建的是一个异步任务,而不是直接创建线程。任务的执行方式取决于系统的资源情况:join()
来等待线程完成,否则可能导致资源泄漏。get()
或wait()
方法调用时执行。在使用std::async时,可能会遇到不确定性问题。例如,系统可能选择使用std::launch::deferred
(延迟调用)或std::launch::async
(立即创建新线程)。要解决这种不确定性,可以通过以下方式判断任务执行情况:
#include#include #include #include using namespace std;int mythread() { cout << "mythread start" << "ThreadId = " << this_thread::get_id() << endl; cout << "mythread end" << "ThreadId = " << this_thread::get_id() << endl; return 100;}int main() { cout << "MainThreadID = " << this_thread::get_id() << endl; future result = async(mythread); future_status status = result.wait_for(0s); // 等待0秒判断状态 if (status == future_status::deferred) { cout << result.get() << endl; } else if (status == future_status::ready) { cout << "线程成功执行完毕并返回!" << endl; cout << result.get() << endl; } else if (status == future_status::timeout) { cout << "超时线程没执行完!" << endl; cout << result.get() << endl; } return 0;}
通过result.wait_for(0s)
,可以判断异步任务的执行方式:
std::async与std::thread在多线程编程中的应用场景有显著不同。std::async更注重灵活性和资源管理,适合在资源有限的情况下使用。通过合理配置launch策略和检查future状态,可以有效应对异步任务的不确定性问题。在实际开发中,应根据具体需求选择适合的线程创建方式,同时注意资源管理和状态判断,以确保程序的稳定性和性能。
转载地址:http://zdyr.baihongyu.com/