参考深入理解C++11新特性————原子操作
1. 循环外加锁,效率高于循坏内加锁。(循环内加锁效率令人发指)
#include <iostream>
#include <thread>
#include <mutex>
long long total = 0;
std::mutex g_mutex;
void Inner_mutex_thread(){
for (long long i = 0; i < 100000000LL; i++)
{
g_mutex.lock();
total += i;
g_mutex.unlock();
}
}
void Out_mutex_thread(){
g_mutex.lock();
for (long long i = 0; i < 100000000LL; i++)
{
total += i;
}
g_mutex.unlock();
}
循环内加锁,两个线程抢占资源
int main()
{
clock_t s = clock();
std::thread t(Inner_mutex_thread);
std::thread t2(Inner_mutex_thread);
t.join();
t2.join();
clock_t e = clock();
std::cout << "total = " << total << std::endl
<< "time = " << (e - s) << std::endl;
return 0;
}
输出:
total = 9999999900000000
time = 98375
循环外加锁,两个线程抢夺资源
int main()
{
clock_t s = clock();
std::thread t(Out_mutex_thread);
std::thread t2(Out_mutex_thread);
t.join();
t2.join();
clock_t e = clock();
std::cout << "total = " << total << std::endl
<< "time = " << (e - s) << std::endl;
return 0;
}
输出:
total = 9999999900000000
time = 686
2. 原子操作*
原子操作:多线程程序中“最小且不可并行化的”操作。原子操作都是通过互斥的访问来保证的。
在C++11中,程序员不需要为原子数据类型显示的声明互斥锁,或者调用加锁,解锁的API,线程能够互斥的对原子类型进行访问。
所以原子操作类似于串行编程,不用考虑加锁,解锁操作,降低了多线程编程难度。
#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
std::atomic<long long> total = 0; // 原子数据
void atomic_thread(){
for (long long i = 0; i < 100000000LL; i++)
{
total += i;
}
}
int main()
{
clock_t s = clock();
std::thread t(atomic_thread);
std::thread t2(atomic_thread);
t.join();
t2.join();
clock_t e = clock();
std::cout << "total = " << total << std::endl
<< "time = " << (e - s) << std::endl;
return 0;
}
输出:
total = 9999999900000000
time = 18112
效率上:循环外加锁 大于 原子操作 大于 循环内加索