1)promise(保证)和future的联合使用,实现两个线程的数据传递
#include
#include
#include
using namespace std;
//promise用法:可以给线程一个值,而从另一个线程读出该值
// 实现了两个线程的数据传递!
void myPromise(std::promise<int>& tmp,int num)//promise线程
{
//在这里假使处理复杂的计算,最后得出一个值,并返回
num = num + 20;
tmp.set_value(num);
}
//另一个线程可以得到promise计算后得到的值
void myFuture(std::future<int>& tmp)
{
cout<<"myFuture thread receive value is : "<< tmp.get()<<endl;
}
int main()
{
std::promise<int> pro;
std::thread th1(myPromise,std::ref(pro),10); //创建promise线程时,第二个参数一定要用引用
th1.join();
std::future<int> result = pro.get_future();
std::thread th2(myFuture,std::ref(result)); //std::ref( pro.get_future())用临时对象不可以;
th2.join();
return 0;
}
//输出结果:myFuture thread receive value is : 30
2) package_task的使用,把任务从新包装起来,案例代码如下:
#include
#include
#include
using namespace std;
int func(void)
{
cout<<"start----- thread_id is : "<<std::this_thread::get_id()<<endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
cout<<"end-------- thread_id is : "<<std::this_thread::get_id()<<endl;
return 5;
}
//package_task类模板,可以包装任何可调用对象
int main()
{
std::packaged_task<int()> task(func);
std::thread th(std::ref(task)); //package_task里面有一个成员函数get_future(),可以返回一个future对象;
th.join();
std::future<int> result = task.get_future();
cout<<result.get()<<endl;
return 0;
}
3)//std::async和std::future一起配合使用
#include
#include
#include
#include
#include
// std::async和std::future的用法:
// async是一个函数模板,启动一个线程;std::future是类模板,当async启动任务后,会返回std::future对象;
// std::future对象里面有需要的返回值;
using namespace std;
int func(void)
{
cout<<"start----- thread_id is : "<<std::this_thread::get_id()<<endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
cout<<"end-------- thread_id is : "<<std::this_thread::get_id()<<endl;
return 5;
}
//std::launch::deferred参数时,等待wait或者get返回,如果没有这两个函数,直接运行接下来代码
//std::launch::deferred参数不会创建新线程!!!
//std::future两个成员函数,get是等待线程处理完返回结果;wait是等待线程处理完,不返回结果
int main()
{
cout<<"main thread start----- thread_id is : "<<std::this_thread::get_id()<<endl;
std::future<int> result = std::async(func); //程序不会卡到这里!!!这里存在一个绑定关系
cout<<"********main run*********"<<endl;
cout<<result.get()<<endl; //程序会卡到这里,等待线程返回结果(利用的是std::future的成员函数get)
return 0;
}
4)//条件变量与互斥量的配合使用方法:
#include
#include
#include
#include
#include
//条件变量是和互斥量配合使用!
using namespace std;
class A
{
public:
void inQueue(void)
{
for(int i = 0; i<10000;i++)
{
cout<<"insert message : "<<i<<endl;
{
std::unique_lock<std::mutex> uniqueLock(mtx);
message.push_back(i);
cond.notify_one();
}
}
}
void outQueue(void)
{
for(int i = 0 ; i<10000; i++)
{
std::unique_lock<std::mutex> uniqueLock(mtx); //自动加锁
//wait跟互斥量的关系:wait阻塞解锁,wait唤醒加锁!!!
cond.wait(uniqueLock,[this](){ //如果参数2是false,解锁等待;如果是true,加锁完成后,继续执行下面代码
if(!message.empty())
return true;
else
return false; //可以处理虚假唤醒,就是说容器没有数据,但被唤醒了,执行解锁等待。
});
int cmd = message.front();
message.pop_front();
cout<<"out cmd---------- is :"<<cmd<<endl;
}//出作用域,uniqueLock锁释放;
}
private:
std::list<int> message;
std::condition_variable cond;
std::mutex mtx;
};
int main()
{
A a;
std::thread th1(&A::inQueue,&a);
std::thread th2(&A::outQueue,&a);
th1.join();
th2.join();
return 0;
}
5)互斥量的使用方法:
#include
#include
#include
#include
#include
using namespace std;
class A
{
public:
void inQueue(void)
{
for(int i = 0; i<10000;i++)
{
cout<<"insert message : "<<i<<endl;
{
std::unique_lock<std::mutex> uniqueLock(mtx);
message.push_back(i);
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
void outQueue(void)
{
for(int i = 0; i<10000;i++)
{
if(!message.empty())
{
int cmd = 0;
{
std::unique_lock<std::mutex> uniqueLock(mtx);
cmd = message.front();
message.pop_front();
}
cout<<"out cmd is :"<<cmd<<endl;
}
else
{
cout<<"empty---------------i: "<<i<<endl;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
private:
std::list<int> message;
std::mutex mtx;
};
int main()
{
A a;
std::thread th1(&A::inQueue,&a);
std::thread th2(&A::outQueue,&a);
th1.join();
th2.join();
return 0;
}
6)单例模式在线程中的使用
#include
#include
#include
using namespace std;
std::mutex mtxRes;
//单例目的:即使多个线程被创建,也要保证只创建一个对象,所以创建多线程创建对象时,要做互斥量条件判断!!!
class A
{
private:
A(){cout<<"A conctructor---"<<endl;}
private:
static A* m_instance; //声明一个静态私有类指针变量
public:
static A* getInstance()
{
if(m_instance == nullptr) //多个线程,为了提升速度(双重锁定)
{
std::unique_lock<std::mutex> uniquelock(mtxRes);
if(m_instance == nullptr)
{
m_instance = new A();
static garb cl;//为了程序退出后,能够正常删除m_instance
}
}
return m_instance;
}
void test(void)
{
cout<<"test------"<<endl;
}
class garb //为了能正常delete m_instance,而设计的内部类
{
public:
~garb()
{
if(A::m_instance != nullptr)
{
delete A::m_instance;
A::m_instance = nullptr;
}
}
};
};
A* A::m_instance = nullptr;
void func(void)
{
cout<<"-----开始单例模式创建--------"<<endl;
A::getInstance()->test();
cout<<"-----单例模式创建完成--------"<<endl;
}
int main()
{
// A::getInstance()->test();
std::thread th1(func);
std::thread th2(func);
th1.join();
th2.join();
return 0;
}