pthread与thread
C++11中使用thread,C++98 中使用pthread,并且pthread只支持Linux。
创建线程
#include<thread>//创建线程需要的头文件
#include<mutex>//锁的头文件
假设有如下两个函数:
int number = 0;//全局变量
mutex g_lock;//锁
int threadProc1()
{
lock_guard<mutex> locker(g_lock);
for (int i = 0; i < 200; i++)
{
//g_lock.lock();
cout << "thread 1:" << number << endl;
++number;
//g_lock.unlock();
this_thread::sleep_for(chrono::milliseconds(10));
}
return 0;
}
int thread2Proc2()
{
lock_guard<mutex> locker(g_lock);
for(int i=0;i<200;i++)
{
//g_lock.lock();
cout << "thread2:" << number << endl;
--number;
//g_lock.unlock();
this_thread::sleep_for(chrono::milliseconds(10));
}
return 0;
}
创建线程的步骤为:在main函数中定义两个线程,并将对应的函数放进去即可
int main()
{
thread t1(threadProc1);
thread t2(thread2Proc2);
t1.detach();
t2.detach();
system("pause");
return 0;
}
C++11中使用锁
mutex
在上述的例子中,全局变量g_lock
是互斥锁,能够实现资源的互斥访问。一般包括两个步骤:上锁g_lock.lock()
,和解锁g_lock.unlock()
。上锁和解锁直接加在对应的变量前后即可,但是需要注意加锁后必须记得解锁。面对比较大的工程,忘记解锁或者程序异常等导致解锁失败是难免的,所以C++11提供了lock_guard
类管理锁。
lock_guard
lock_guard
类在构造函数中加锁(lock),在自己的生命周期内一直变量一直被锁,当lock_guard
析构的时候解锁(unlock),此时完成自动解锁,开发者不需要手动上锁解锁。
在上述代码中,例如:
int threadProc1()
{
lock_guard<mutex> locker(g_lock);//定义lock_guard变量,对g_lock进行管理
for (int i = 0; i < 200; i++)
{
//g_lock.lock();
cout << "thread 1:" << number << endl;
++number;
//g_lock.unlock();
this_thread::sleep_for(chrono::milliseconds(10));
}
return 0;
}
上述代码在函数threadProc1()
运行期间,变量number就一直处于被锁定的状态,因为lock_guard的作用区间是自己的整个生命周期。所以这样写的话,两个线程就没有什么意义了,所以如果是对某一个变量加锁解锁的话,可以再循环内实现
int threadProc1()
{
for (int i = 0; i < 200; i++)
{
lock_guard<mutex> locker(g_lock);
cout << "thread 1:" << number << endl;
++number;
this_thread::sleep_for(chrono::milliseconds(10));
}
return 0;
}
上述在每一个i循环中都会构造和析构locker从而完成在循环内部对变量的加锁和解锁。