关于c:C并发与多线程-11sharedfutureautomic

40次阅读

共计 3214 个字符,预计需要花费 9 分钟才能阅读完成。

std::shared_future

 类模板

template <class T>  shared_future;
template <class R&> shared_future<R&>;   // specialization : T is a reference type (R&)
template <>         shared_future<void>; // specialization : T is void
  • 一个 shared_future 对象行为相似于 future 对象,除了它能够被赋值,而且一个以上的 shared_future 能够在他们的共享状态完结时共享所有权。它们还被容许一旦筹备好就屡次检索共享状态下的值。
  • shared_future 对象能够从 future 对象隐式转换,也能够通过 future::share 显式取得。在这两种状况下,原 future 对象本身将生效。
  • 共享状态的生存期至多要继续到与之关联的最初一个对象被销毁为止。从 shared_future 中获取值(应用成员函数 get)不会开释其对共享状态的所有权(与 future 不同)。因而,如果与 shared_future 对象相关联,则共享状态能够在最后取得它的对象(如果有的话)之后持续存在。
成员函数 形容
get 当共享状态就绪时,返回存储在共享状态中的值的援用(或引发其异样)
valid 查看 shared_future 对象是否与共享状态关联
wait 期待共享状态准备就绪
wait_for 期待共享状态在 rel_time 指定的工夫内准备就绪
wait_until 期待共享状态准备就绪,最多直到 abs_time 工夫点
#include <iostream>
#include <thread>
#include <future>

using namespace::std;

int mythread()
{
    cout << "mythread begin" << endl;

    this_thread::sleep_for(chrono::microseconds(5000));

    cout << "mythread end" << endl;

    return 5;
}

int main()
{
    cout << "main begin" << endl;

    future<int> result = async(launch::async, mythread);
    shared_future<int> result_s = result.share();

    // 等价
    // shared_future<int> result_s = async(launch::async, mythread);

    if (result_s.valid())
    {cout << result_s.get() << endl;

        cout << result_s.get() << endl;

        cout << result_s.get() << endl;}

    cout << "main end" << endl;

    return 0;
}

输入:

main begin
mythread begin
mythread end
5
5
5
main end

std::atomic 原子操作

 类模板

template <class T> struct atomic;
  • 原子操作是指不会被线程调度机制打断的操作。这种操作一旦开始,就始终运行到完结,两头不会有任何任何上下文切换。
  • 原子操作能够是一个步骤,也能够是多个操作步骤,但其程序不可被打乱,也不能够被切合只执行其中一部分。
  • 将整个操作视作一个整体是原子操作的外围特色。

编程试验

  • 非原子操作,不加锁,效率很高,但无奈失去正确的后果
  • 非原子操作,加锁,效率很低,但后果正确
  • 原子操作,效率很高,且后果正确

测试 1:非原子操作,无锁

#include <iostream>
#include <thread>

using namespace::std;

int g_sum = 0;

void add()
{for (uint32_t i=0; i<10000000; ++i)
        ++g_sum;
}

int main()
{auto beginTime = clock();

   thread t1(add);
   thread t2(add);

   t1.join();
   t2.join();

   auto endTime = clock();

   cout << "time consuming  :" << endTime - beginTime << endl;
   cout << "calculated value:" <<  g_sum << endl;

    return 0;
}

输入:[速度快,后果谬误]

time consuming  : 47
calculated value: 10856025

测试 2:非原子操作,有锁

#include <iostream>
#include <thread>
#include <mutex>

using namespace::std;

int g_sum = 0;
mutex g_mutex;

void add()
{for (uint32_t i=0; i<10000000; ++i)
    {g_mutex.lock();
        ++g_sum;
        g_mutex.unlock();}
}

int main()
{auto beginTime = clock();

   thread t1(add);
   thread t2(add);

   t1.join();
   t2.join();

   auto endTime = clock();

   cout << "time consuming  :" << endTime - beginTime << endl;
   cout << "calculated value:" <<  g_sum << endl;

    return 0;
}

输入:[后果正确,速度慢]

time consuming  : 571
calculated value: 20000000

测试 3:原子操作

#include <iostream>
#include <thread>
#include <atomic>

using namespace::std;

atomic<int> g_sum {0};

void add()
{for (uint32_t i=0; i<10000000; ++i)
    {++g_sum;}
}

int main()
{auto beginTime = clock();

   thread t1(add);
   thread t2(add);

   t1.join();
   t2.join();

   auto endTime = clock();

   cout << "time consuming  :" << endTime - beginTime << endl;
   cout << "calculated value:" <<  g_sum << endl;

    return 0;
}

输入:[速度快,后果正确]

time consuming  : 292
calculated value: 20000000

个别用法

  • 用于多线程环境中的拜访标记
  • 用于多线程环境中的拜访统计
#include <iostream>
#include <thread>
#include <atomic>

using namespace::std;

atomic<bool> g_ifEnd {false};

void mythread()
{
    cout << "mythread begin" << endl;

    chrono::microseconds dura(1000);

    while (!g_ifEnd)
    {cout << "mythread thread id :" << this_thread::get_id() << endl;

        this_thread::sleep_for(dura);
    }

    cout << "mythread begin" << endl;
}

int main()
{
   cout << "main end" << endl;

   thread t1(mythread);

   this_thread::sleep_for(chrono::microseconds(5000));

   g_ifEnd = true;

   t1.join();

   cout << "main end" << endl;

    return 0;
}

输入:

main end
mythread begin
mythread thread id :2
mythread begin
main end

正文完
 0