C++ 11 thread 基础用法 lock unlock join mutex joinable lock_guard unique_lock condition_variable wait notify_one notify_all asnyc future packaged_task promise

#include "pch.h"
#include<iostream>
#include<string>
#include<vector>
#include<list>
// 线程相关头文件
#include<thread>
#include<mutex>
#include<future>
using namespace std;

static int res = 0; //共享变量 演示使用互斥量读写。

mutex my_mutex; //互斥量
mutex my_mutex2;
void test() //不带参数
{
auto id=this_thread::get_id();
cout << "无参数id="<<id << endl;
/* 互斥量保护数据的lock 和unlock形式 */
my_mutex.lock();
// lock(my_mutex, my_mutex2); 相当于同时lock了所有互斥量
res = 1;
my_mutex.unlock(); //成双成对。
return;
}
void test2(int )
{
auto id = this_thread::get_id();
cout << "带参数id="<<id <<endl;
/*
互斥量保护数据的lock_guard 形式。
参数有adopt_lock(结构体对象)作用是表示互斥量已经lock了。
*/
lock_guard<mutex>my_lock(my_mutex); //lock_guard<mutex>my_lock(my_mutex,adopt_lock); 。
res = 2;
return;
}
class A
{
public:
void operator()() //不能带参数
{
auto id = this_thread::get_id();
cout << "类对象id="<<id << endl;
return;
}
//call_once
static void once()
{
return;
}
};
void second()
{
return;
}
void my_async();
void my_packaged();
void my_promise_();
int main()
{
int temp;
thread my_thread(test);
//第一个参数为可调用对象,包括函数,类(必须定义了()重载运算符),lambda表达式,后续参数为函数对应参数。
thread my_thread2(test2,temp);
// join 等待子线程执行完毕再回到主线程

if (my_thread.joinable()) //joinable判断子线程是否能join/detach
{
my_thread.join();
}
//一个线程只能join一次
my_thread2.join();
/* detach 不等待子线程 (尽量不使用)
my_thread.detach();
my_thread2.detach();
*/
A a;
thread my_thread3(a);
my_thread3.join();

//call_once()具备互斥量能力,保证函数只执行一次 并且更高效。需要结合标记once_flag(也是一个结构)使用
once_flag g_flag;
once_flag p_flag;
call_once(g_flag, A::once);
call_once(p_flag, second);
//async future 相关。
my_async();
my_packaged();
my_promise_();
cout << "I love China!" << endl;
return 0;
}

// 更灵活的 unique_lock 类模板。 可以取代lock_guard 不需要自己unlock 第二个参数有adopt_lock(同lock_guard,前提是先lock)


//try_to_lock(前提是不能先lock,不阻塞线程。)

// defer_lock(前提是不能先lock,初始化不加锁的mutex) 可以直接调用成员函数。

// 成员函数lock()

//unlock()

//try_lock() my_unique。try_lock()==true 表示拿到锁,没拿到锁就干其他事。

// release() 返回mutex对象指针 并释放所有权 mutex *ptr=my_unique.release(); ptr->unlock();

//unique_lock<mutex>my_unique(my_mutex) 锁住的代码越少,粒度越细。

//unique_lock<mutex>my_unique2(move::my_unique) //所有权转移

/*------------------------------------------------------------------------------

condition_variable wait() notify_one notify_all

condition_variable my_cond 生成条件变量对象,需要互斥量配合工作

wait 等待 notify_one 唤醒 notify_all 唤醒所有wait

------------------------------------------------------------------------------*/

condition_variable my_cond;
mutex my_mutex3;
bool juge()
{
if (true)
{
return true;
}
return false;
}

void outmsg()
{
int command = 0;
while (true)
{
unique_lock<mutex>my_mu(my_mutex3);
my_cond.wait(my_mu, juge);

//第二个参数返回false 那么解锁互斥量,并堵塞,直到其他线程调用notify_once()成员函数为止。
//第二个参数缺省值为false

//一顿操作。。。

//可以防止后续操作缺少条件(比如共享消息队列没有消息无法读取则需要wait 写操作写入数据。)

//mes.pop_back() 读取第一条消息。

break;
}
}

void inmsg()
{
for (int i = 0;i < 100000;++i)
{
unique_lock<mutex>my_mu(my_mutex3);
//一顿操作
my_cond.notify_one(); //尝试唤醒wait() mutex锁之后被释放了。

//notify_all() 唤醒所有wait();
}

}
/*------------------------------------------------------------------------------

async 启动一个异步任务(自动创建一个线程)并返回值,返回future类模板。

future 提供访问异步操作返回结果的机制。

packaged_task 包装函数

promise 类模板,在某个线程中赋值,在另一个线程中提取 promise<int>my_promise;

------------------------------------------------------------------------------*/

int mythread()
{
auto id = this_thread::get_id();
cout << "async 的 id=" << id << endl;
//使线程睡觉5秒
chrono::milliseconds dura(5000);
this_thread::sleep_for(dura);
cout << "async 的 id=" << id << endl;
return 5;
}

void my_async()
{
//future<int>result = async(mythread);
//缺省参数为async 无需等待。
future<int>result = async(launch::deferred,mythread); //如果是调用类的成员函数 future<int>result = async(&A::mythread,&Aobj,成员函数参数);

//asnyc可以接受额外参数 std::launch枚举类型

//deferred 延迟调用,直到调用get()和wait()线程才执行,如果没这两函数,那么线程不会被创建。

cout << "continue....." << endl;
cout << "continue....." << endl;
cout << "continue....." << endl;
cout << "continue....." << endl;
//用get()返回线程结果。不拿到返回值誓不罢休。
cout << "async返回的结果="<<result.get() << endl;
return;
}
int mythread1(int mypt)
{
return mypt;
}

void my_packaged()
{
packaged_task<int(int)>mypt(mythread1);

/* lambda表达式
packaged_task<int(int)>mypt([](int mypar)
{

}
); */

thread my_pt(ref(mypt), 1);
my_pt.join();
future<int>res = mypt.get_future();
cout << "packaged返回结果:"<<res.get() << endl;
return;
}

void my_promise(promise<int>&temp,int cur)
{
cur++;
cur *= 10;
int result = cur; //保存结果
temp.set_value(result); //结果放在promise之中

}

void my_promise_()
{
promise<int>myprom;
thread t(my_promise, ref(myprom), 10);
t.join();
future<int>fu = myprom.get_future();
int result=fu.get();
cout << "promise结果=" << result<<endl;
return;
}

猜你喜欢

转载自www.cnblogs.com/yangshengjing/p/11621238.html