为了保证对某个资源的操作是原子性的(对资源读写时,只有当前的操作结束,才允许另外线程对其操作,这里有个理解误区,资源操作原子性不是说,当前某个线程获得了某个资源使用权,然后线程执行时间完毕,要切换线程了,因为资源操作是原子性的,所以它就阻止线程切换,这是不可能的,要是某个程序里获得资源不放,那么操作系统上其他程序都不能跑咯。当然不是,原子操作的意思是,某个线程获得了某个资源的使用权,其他资源也想获得该资源的使用权时只能等待--等待会导致线程切换(节约CPU时间),只有当获得资源使用权的线程释放了资源使用权,则其他线程就可以操作)
代码是在多线程运行中是可以重入的。
下面分别给出QMutex和std::mutex的写法,都非常简单,写出来留个记录。
1 #include <thread> 2 #include <iostream> 3 #include <chrono> 4 #include <QMutex> 5 #include <QMutexLocker> 6 7 using namespace std; 8 9 QMutex mutex; 10 11 void ThreadFunc(void) 12 { 13 QMutexLocker locker(&mutex); 14 cout<<"Enter Func "<<std::this_thread::get_id()<<endl; 15 16 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 17 18 cout<<"Exit Func "<<std::this_thread::get_id()<<endl; 19 } 20 21 int main(int argc, char *argv[]) 22 { 23 thread t1(ThreadFunc); 24 thread t2(ThreadFunc); 25 thread t3(ThreadFunc); 26 27 t1.join(); 28 t2.join(); 29 t3.join(); 30 std::this_thread::sleep_for(std::chrono::milliseconds(5000)); 31 32 cout<<"Main Thread Exit"<<endl; 33 34 return 0; 35 }
1 #include <thread> 2 #include <iostream> 3 #include <chrono> 4 #include <mutex> 5 6 using namespace std; 7 8 mutex tmutex; 9 10 void ThreadFunc(void) 11 { 12 std::lock_guard<std::mutex> locker(tmutex); 13 cout<<"Enter Func "<<std::this_thread::get_id()<<endl; 14 15 std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 16 17 cout<<"Exit Func "<<std::this_thread::get_id()<<endl; 18 } 19 20 int main(int argc, char *argv[]) 21 { 22 thread t1(ThreadFunc); 23 thread t2(ThreadFunc); 24 thread t3(ThreadFunc); 25 26 t1.join(); 27 t2.join(); 28 t3.join(); 29 std::this_thread::sleep_for(std::chrono::milliseconds(5000)); 30 31 cout<<"Main Thread Exit"<<endl; 32 33 return 0; 34 }