笔记_async_future_promise_future成员函数_原子操作std::atomic

async future

作用:

创建后台任务并返回值

定义:

async 是一个函数模板,用来启动一个异步任务,启动后会返回一个future类模板对象(线程返回的结果)

实现:


可以通过调用future的成员函数get()获取结果
调用get时,等待入口函数执行完毕,拿到结果后才往下走。
wait只是等待,并不返回结果

代码:

int mythread4()
{
    cout << "mythread4()start  " << "threadid:" << std::this_thread::get_id() << endl;
    std::chrono::milliseconds dure(3000);
    std::this_thread::sleep_for(dure);
    cout << "mythread4()end  " <<"threadid:"<< std::this_thread::get_id() << endl;
    return 555;
}
int main()
{

    std::future<int> result = std::async(mythread4);
    cout << result.get() << endl;
    result.wait();
    return 0;
}


如果不用等待也不用get,可能主线程会先执行

可以额外向std::async传递一个参数,类型为std::lunnch类型(枚举类型)
launch::deferred:表示线程入口函数调用倍延迟到std::future的wait()或者get调用时才执行

std::future<int> result = std::async(std::launch::deferred,&TempClassA::mythread4,&A,55);
后面不调用get或者wait这行算白写。

launch::async

是直接在此处创建线程

std::packaged_task

定义:

类模板,模板参数是各种可调用对象,通过std::packaged_task 把各种可调用对象包装起来,方便将来作为
线程入口函数

int mythread4(int tempA)
{
    cout << "mythread4()start  " << "threadid:" << std::this_thread::get_id() << endl;
    std::chrono::milliseconds dure(3000);
    std::this_thread::sleep_for(dure);
    cout << "mythread4()end  " << "threadid:" << std::this_thread::get_id() << endl;
    return tempA;
}
int main()
{
    cout << "Main  " << "threadid:" << std::this_thread::get_id() << endl;
    using def = int(int);
    std::packaged_task<int(int)>myobj(mythread4);
    std::thread t1(std::ref(myobj),2333);
    t1.join();
    std::future<int> result = myobj.get_future();
    cout << result.get() << endl;
    return 0;
}

利用Vctor容器来存储Packaged_task(其中Packaged_task也是可调用对象)

int main()
{
std::packaged_task<int(int)>myobj([](int tempA)
    {
        cout << "mythread4()start  " << "threadid:" << std::this_thread::get_id() << endl;
        std::chrono::milliseconds dure(3000);
        std::this_thread::sleep_for(dure);
        cout << "mythread4()end  " << "threadid:" << std::this_thread::get_id() << endl;
        return tempA;
    });
    vector<std::packaged_task<int(int)>> m_vector3;
    m_vector3.push_back(std::move(myobj));
    std::packaged_task<int(int)>myobj2;
    auto begin_i = m_vector3.begin();
    myobj2 = std::move(*begin_i);
    m_vector3.erase(begin_i);
    myobj2(2333);
    std::future<int> result = myobj2.get_future();
    cout << result.get() << endl;
    return 0;
}

std::promise

定义:


我们能够在某个线程中给它赋值,然后我们可以在其他线程中,把这个值取出来用

void mythread4(std::promise<int>&tmp,int cal)
{
    cout << "mythread4()start  " << "threadid:" << std::this_thread::get_id() << endl;
    std::chrono::milliseconds dure(3000);
    std::this_thread::sleep_for(dure);
    cal += 1000;
    int result = cal;
    tmp.set_value(result);//结果保存到了tmp这个对象中
    cout << "mythread4()end  " << "threadid:" << std::this_thread::get_id() << endl;
}
void getfuture(std::future<int> &temp)
{
    auto result = temp.get();
    cout << "result:" << result << endl;
}
int main()
{
    std::promise<int> myprom;
    std::thread t1(mythread4, ref(myprom),100);
    t1.join();
    std::future<int> fu1 = myprom.get_future();
    std::thread t2(getfuture,std::ref(fu1));
    t2.join();
    cout << "end!" << endl;
    return 0;
}

future成员函数

future_status 状态,是一个枚举值

int mythread4(int cal)
{
    cout << "mythread4()start  " << "threadid:" << std::this_thread::get_id() << endl;
    std::chrono::milliseconds dure(3000);
    std::this_thread::sleep_for(dure);
    cout << "mythread4()end  " << "threadid:" << std::this_thread::get_id() << endl;
    return cal;
}
int main()
{

    std::future<int> fu1 = std::async(std::launch::deferred,mythread4,2333);
    std::future_status  status = fu1.wait_for(std::chrono::seconds(6));
    if (status == std::future_status::timeout)//等待1s,线程执行了5s,超时了
    {
        cout << "超时了!" << endl;
    }else if(status == std::future_status::ready)//等待6s,线程执行了5s,正常返回
    {
        cout << "线程成功返回" << endl;
    }else if (status == std::future_status::deferred)//如果async第一个参数设置为deffered,这里成立
    {
        cout << "线程没延迟执行,用get才能执行" << endl;
        cout << fu1.get() << endl;//而且实际是在主线程执行,根本没有创建线程
    }
    cout << "end!" << endl;
    return 0;
}

std::shared_future

get()只能获取一次,因为get是一个移动语义,第二次get会报一个异常,因为之前的get已经被移动了,现在是空的了。

int mythread4(int cal)
{
    cout << "mythread4()start  " << "threadid:" << std::this_thread::get_id() << endl;
    std::chrono::milliseconds dure(3000);
    std::this_thread::sleep_for(dure);
    cal += 2000;
    cout << "mythread4()end  " << "threadid:" << std::this_thread::get_id() << endl;
    return cal;
}
void getfuture(std::shared_future<int> &temp)
{
    auto result = temp.get();
    cout << "result:" << result << endl;
}
int main()
{
    std::future<int> fu1 = std::async(mythread4,333);
    //std::shared_future<int> fu2(std::move(fu1));//两种写法一致
    std::shared_future<int> fu3(fu1.share());//两种写法一致
    cout<<fu3.get()<<endl;
    cout << "end!" << endl;
    return 0;
}

原子操作std::atomic

理解为一种不需要用到互斥量加锁的多线程并发编程方式。
原子操作:是在多线程中不会被打断的程序执行片段,而且效率比互斥要高很多
针对的一般是一个变量,而不是一个代码段,这是它的限制。
一般操作要么是完成的,要么是没完成的,没有中间值

std::atomic也是个类模板,是用来封装某个类型的值

std::atomic<int> staInt = 0;//一个类型为int的对象(值)
void funThread()
{
    for (int i = 0; i < 100000; i++)
    {
        staInt++;
    }
}
int main()
{
    std::thread mt1(funThread);
    std::thread mt2(funThread);
    mt1.join();
    mt2.join();
    cout << staInt << endl;
    return 0;
}


一般计数或者统计的时候,累计发送了多少个数据包,收到了多少?可以用原子操作
 

猜你喜欢

转载自blog.csdn.net/qq_35337794/article/details/121702574