总结c++11&14-多线程要点

这篇文章主要总结c++11&14-多线程要点,内容简而易懂,希望大家可以学习一下,学习完之后肯定会有收获的,下面让小编带大家一起来看看吧。

在成都网站设计、成都网站制作、外贸网站建设过程中,需要针对客户的行业特点、产品特性、目标受众和市场情况进行定位分析,以确定网站的风格、色彩、版式、交互等方面的设计方向。创新互联建站还需要根据客户的需求进行功能模块的开发和设计,包括内容管理、前台展示、用户权限管理、数据统计和安全保护等功能。

在C++11以前,C++的多线程编程均需依赖系统或第三方接口实现,一定程度上影响了代码的移植性。C++11中,引入了boost库中的多线程部分内容,形成C++标准,形成标准后的boost多线程编程部分接口基本没有变化,这样方便了以前使用boost接口开发的使用者切换使用C++标准接口,很容易把boost接口升级为C++标准接口。

我们通过如下几部分介绍C++11多线程方面的接口及使用方法。

1. std::thread

std::thread为C++11的线程类,使用方法和boost接口一样,非常方便,同时,C++11的std::thread解决了boost::thread中构成参数限制的问题,我想这都是得益于C++11的可变参数的设计风格。

我们通过如下代码熟悉下std::thread使用风格:

//c11.cpp
#include 
#include 
void threadfun1()
{
 std::cout << "threadfun1 - 1\r\n" << std::endl;
 std::this_thread::sleep_for(std::chrono::seconds(1));
 std::cout << "threadfun1 - 2" << std::endl;
}
void threadfun2(int iParam, std::string sParam)
{
 std::cout << "threadfun2 - 1" << std::endl;
 std::this_thread::sleep_for(std::chrono::seconds(5));
 std::cout << "threadfun2 - 2" << std::endl;
}
int main()
{
 std::thread t1(threadfun1);
 std::thread t2(threadfun2, 10, "abc");
 t1.join();
 std::cout << "join" << std::endl;
 t2.detach();
 std::cout << "detach" << std::endl;
}

注意编译时要使用:g++ c11.cpp -lpthread

运行结果:

threadfun1 - 1
threadfun2 - 1
threadfun1 - 2
join
detach

2. std::atomic

std::atomic为C++11封装的原子数据类型。
什么是原子数据类型?从功能上看,简单地说,原子数据类型不会发生数据竞争,能直接用在多线程中而不必我们用户对其进行添加互斥资源锁的类型。从实现上来看,我们可以理解为这些原子类型内部自己加了锁。

我们下面通过一个测试例子说明原子类型std::atomic的特点。

我们使用10个线程,把std::atomic类型的变量iCount从10减到1。

//c11.cpp
#include 
#include 
#include 
#include 
#include 
std::atomic bIsReady(false);
std::atomic iCount(10);
void threadfun1()
{
 if (!bIsReady) {
  std::this_thread::yield();
 }
 while (iCount > 0)
 {
  printf("iCount:%d\r\n", iCount--);
 }
}
int main()
{
 std::list lstThread;
 for (int i = 0; i < 10; ++i)
 {
  lstThread.push_back(std::thread(threadfun1));
 }
 for (auto& th : lstThread)
 {
  th.join();
 }
}

运行结果:

iCount:10
iCount:9
iCount:8
iCount:7
iCount:6
iCount:5
iCount:4
iCount:3
iCount:2
iCount:1

从上面的结果可以看到,iCount的最小结果是1,没有出现小于等于0的情况,大家可以把iCount改成100甚至1000看看,可能会更直观一点。

3. std::condition_variable

C++11中的std::condition_variable就像Linux下使用pthread_cond_wait和pthread_cond_signal一样,可以让线程休眠,直到被唤醒,然后再重新执行。线程等待在多线程编程中使用非常频繁,经常需要等待一些异步执行的条件的返回结果。

代码如下:

#include  // std::cout
#include  // std::thread
#include  // std::mutex, std::unique_lock
#include  // std::condition_variable
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void print_id(int id) {
 std::unique_lock lck(mtx);
 while (!ready) cv.wait(lck); //线程将进入休眠
 // ...
 std::cout << "thread " << id << '\n';
}
void go() {
 std::unique_lock lck(mtx);
 ready = true;
 cv.notify_all();
}
int main()
{
 std::thread threads[10];
 // spawn 10 threads:
 for (int i = 0; i<10; ++i)
  threads[i] = std::thread(print_id, i);
 std::cout << "10 threads ready to race...\n";
 go(); // go!
 for (auto& th : threads) th.join();
 return 0;
}

运行结果:

10 threads ready to race...
thread 0
thread 1
thread 2
thread 3
thread 4
thread 5
thread 6
thread 7
thread 8
thread 9

上面的代码,在调用go函数之前,10个线程都处于休眠状态,当cv.notify_all()运行后,线程休眠结束,继续往下运行,最终输出如上结果。

以上就是关于总结c++11&14-多线程要点的内容,如果你们有学习到知识或者技能,可以把它分享出去让更多的人看到。


分享标题:总结c++11&14-多线程要点
当前链接:http://ybzwz.com/article/jijphj.html