//多线程
#include<thread>
void MultiThread()
{
for(int i = 0; i < 10; i++)
{
printf("Thread1.....\n");
}
}
void main()
{
std::thread th(MultiThread);
printf("Main....\n");
}
直接执行后,出错:
原因:
由于在创建了线程后线程才开始执行,但是主线程并没有停止,仍然执行并退出,线程仍然存在,但是指向他的线程对象销毁,导致该异常!!
解决方法:
保证子线程执行完并退出后,主线程才能退出;
1、thread::join()
使用join()接口可以解决上述问题,该接口的作用是,让主线程等待,知道子线程执行结束:
void main()
{
std::thread th(MultiThread);
th.join();
printf("Main....\n");
}
这样就能正常执行了;
注意:
同一个线程只能join()一次,因为join()一次后,就不再joinable了,thread的
joinable标志会设置成false
2、thread::detach()
上面1中提到的问题,detach函数可以解决,该函数的作用是用来和线程对象分离的,这样线程可以独立执行,不过这样会导致没有thread对象指向该线程而导致该线程的失控,当对象析构时线程会继续在后台执行,但是主程序退出是并不能保证该线程能执行完。
3、mutex
头文件<mutex>,是用来保证线程的同步的,防止不同的线程同时操作一个共享数据;
int num = 0;
std::mutex Lock;
//多线程
void MultiThread1()
{
for(int i = 0; i < 100; i++)
{
Lock.lock();
num++;
Lock.unlock();
printf("Thread1.....,num:[%d]\n",num);
}
}
void MultiThread2()
{
for(int i = 0; i < 100; i++)
{
Lock.lock();
num++;
Lock.unlock();
printf("Thread2.....,num:[%d]\n", num);
}
}
void main()
{
std::thread th1(MultiThread1);
std::thread th2(MultiThread2);
th1.join();
th2.join();
printf("Main....\n");
std::system("pause");
}
但是使用mutex是不安全的,当一个线程在解锁之前异常退出的时候,那其他线程就会阻塞;
4、std::lock_guard
lock_guard相比于上面是相对安全的,因为
lock_guard是基于作用域的,该对象创建的时候,会获取互斥锁,当生命周期结束的时候他会自动析构(解锁),不会因为某个线程的异常退出而阻塞其他线程;
int num = 0;
std::mutex Lock;
//多线程
void MultiThread1()
{
for(int i = 0; i < 100; i++)
{
std::lock_guard<std::mutex> guard_lock1(Lock);
num++;
printf("Thread1.....,num:[%d]\n",num);
}
}
void MultiThread2()
{
for(int i = 0; i < 100; i++)
{
std::lock_guard<std::mutex> guard_lock2(Lock);
num++;
printf("Thread2.....,num:[%d]\n", num);
}
}
void main()
{
std::thread th1(MultiThread1);
std::thread th2(MultiThread2);
th1.join();
th2.join();
printf("Main....\n");
std::system("pause");
}
5、原子变量
由于加锁会导致性能问题,因此,可以使用原子变量:
#include<thread>
#include<atomic>
int LoopNum = 50000000;
std::atomic_int num={0};
std::mutex Lock;//多线程
void MultiThread1()
{
for(int i = 0; i < LoopNum; i++)
{
//std::lock_guard<std::mutex> guard_lock1(Lock);
num++;
}
}
void MultiThread2()
{
for(int i = 0; i < LoopNum; i++)
{
//std::lock_guard<std::mutex> guard_lock2(Lock);
num++;
}
}
void main()
{
std::thread th1(MultiThread1);
std::thread th2(MultiThread2);
th1.join();
th2.join();
printf("Num:[%d]\n",num);
//printf("Main....\n");
std::system("pause");
}