C++11开始支持多线程编程,之前多线程编程都需要系统的支持,在不同的系统下创建线程需要不同的API如pthread_create(),Createthread(),beginthread()等,使用起来都比较复杂,C++11提供了新头文件<thread>、<mutex>、<atomic>、<future>等用于支持多线程。

使用C++11开启一个线程是比较简单的,下面来看一个简单的例子:

  1. #include <thread>
  2. #include <iostream>
  3.  
  4. void hello()
  5. {
  6. std::cout << "Hello from thread " << std::endl;
  7. }
  8.  
  9. int main()
  10. {
  11. std::thread t1(hello);
  12. t1.join();
  13. std::cout << "Main Thread" << std::endl;
  14. return ;
  15. }

运行结果:

说明,通过thread 类直接申明一个线程t1,参数是这个线程执行的回调函数的地址,通过jion()方法阻塞主线程,直到t1线程执行结束为止。

C++11支持Lambda表达式,因此一个新线程的回调函数也可以是有一个Lambda表达式的形式,但是注意如果使用Lambda表达式最好不要使用引用的方式,应该使用值传递的方式来访问数据,在多线程中使用引用容易造成混乱。下面这个例子稍微复杂,创建了多个子线程,并使用了get_id()方法来获取当前线程的id。

  1. #include <thread>
  2. #include <iostream>
  3. #include <vector>
  4.  
  5. int main()
  6. {
  7. std::vector<std::thread> threads;
  8. for(int i = ; i < ; ++i){
  9. threads.push_back(std::thread([](){
  10. std::cout << "Hello from lamda thread " << std::this_thread::get_id() << std::endl;
  11. }));
  12. }
  13.  
  14. for(auto& thread : threads){
  15.  
  16. thread.join();
  17. }
  18. std::cout<<"Main Thread"<<"\t"<<std::this_thread::get_id()<<std::endl;
  19. return ;
  20. }

运行结果:

上述代码中,使用vector来存放每个线程,线程的回调函数通过Lambda表达式产生,注意后面join的使用方式。

可以通过sleep_for来使线程睡眠一定的时间:

  1. #include <thread>
  2. #include <iostream>
  3. #include <mutex>
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8. std::mutex m;
  9. thread t1([&m]()
  10. {
  11. std::this_thread::sleep_for (chrono::seconds());
  12. for(int i=;i<;i++)
  13. {
  14. m.lock();
  15. cout << "In t1 ThreadID : " << std::this_thread::get_id() << ":" << i << endl;
  16. m.unlock ();
  17. }
  18. } );
  19. thread t2([&m]()
  20. {
  21. std::this_thread::sleep_for (chrono::seconds());
  22. for(int i=;i<;i++)
  23. {
  24. m.lock ();
  25. cout << "In t2 ThreadID : " << std::this_thread::get_id() << ":" << i << endl;
  26. m.unlock();
  27. }
  28. } );
  29. t1.join();
  30. t2.join();
  31. cout<<"Main Thread"<<endl;
  32. return ;
  33. }

运行结果:

可以看出,由于线程t1睡眠的时间较长,t2先执行了。

延时有这几种类型:nanoseconds、microseconds、milliseconds、seconds、minutes、hours。

在使用多线程的程序中操作共享数据的时候一定要小心,由于线程的乱序执行,可能会得到意想不到的结果。通过下面的程序来看:

  1. #include <thread>
  2.  
  3. #include <iostream>
  4. #include <vector>
  5. #include <mutex>
  6.  
  7. struct Counter {
  8. std::mutex mutex;
  9. int value;
  10.  
  11. Counter() : value() {}
  12.  
  13. void increment(){
  14. // mutex.lock(); 【1】表示没有使用锁
  15. ++value;
  16. // mutex.unlock(); 【1】
  17. }
  18.  
  19. void decrement(){
  20. mutex.lock();
  21. --value;
  22. mutex.unlock();
  23. }
  24. };
  25.  
  26. int main(){
  27. Counter counter;
  28. std::vector<std::thread> threads;
  29. for(int i = ; i < ; ++i){
  30. threads.push_back(std::thread([&](){
  31. for(int i = ; i < ; ++i){
  32. counter.increment();
  33. }
  34. }));
  35. }
  36. for(auto& thread : threads){
  37. thread.join();
  38. }
  39. std::cout << counter.value << std::endl;
  40. return ;
  41. }

运行结果:

【1】

运行结果:(使用了锁)

说明:由于创建线程是使用lambda表达式,并使用引用的方式访问counter这个变量,当没有使用lock来保护的时候(情况【1】),执行的结果可能不像预期的5000(程序的意思是每个线程使counter中的value自加1000次,5个线程运行结束的时候应该是5000),当没有使用锁的时候自加的操作可能被其他线程打断,因此结果可能会小于5000。

c++11多线程简介的更多相关文章

  1. iOS开发多线程篇—多线程简介

    iOS开发多线程篇-多线程简介 一.进程和线程 1.什么是进程 进程是指在系统中正在执行的一个应用程序 每一个进程之间是独立的.每一个进程均执行在其专用且受保护的内存空间内 比方同一时候打开QQ.Xc ...

  2. Java多线程简介

    Java多线程简介 Java中内置了对多线程的支持,让多线程的开发方便很多,但同时也带来了另外的复杂,线程间的交互以及很多的不确定性让多线程又显得很复杂.在此只是针对Java中多线程的基础做些说明,有 ...

  3. C++11多线程教学(二)

    C++11多线程教学II 从我最近发布的C++11线程教学文章里,我们已经知道C++11线程写法与POSIX的pthreads写法相比,更为简洁.只需很少几个简单概念,我们就能搭建相当复杂的处理图片程 ...

  4. C++11多线程教学(一)

    本篇教学代码可在GitHub获得:https://github.com/sol-prog/threads. 在之前的教学中,我展示了一些最新进的C++11语言内容: 1. 正则表达式(http://s ...

  5. C++11多线程教学II

    从我最近发布的C++11线程教学文章里,我们已经知道C++11线程写法与POSIX的pthreads写法相比,更为简洁.只需很少几个简单概念,我们就能搭建相当复杂的处理图片程序,但是我们回避了线程同步 ...

  6. c++ 11 多线程教学(1)

    本篇教学代码可在GitHub获得:https://github.com/sol-prog/threads. 在之前的教学中,我展示了一些最新进的C++11语言内容: 1. 正则表达式(http://s ...

  7. 多线程简介及GCD的使用

    多线程简介: 对于任意一个iOS应用,程序运行起来后,默认会产生一个主线程(MainThread),主线程专门用来处理UIKit对象的操作,如界面的显示与更新.处理用户事件触发的操作等等.(记忆这点, ...

  8. 【转】C++ 11 并发指南一(C++ 11 多线程初探)

    引言 C++ 11自2011年发布以来已经快两年了,之前一直没怎么关注,直到最近几个月才看了一些C++ 11的新特性,算是记录一下自己学到的东西吧,和大家共勉. 相信Linux程序员都用过Pthrea ...

  9. C++11 并发指南一(C++11 多线程初探)

    引言 C++11 自2011年发布以来已经快两年了,之前一直没怎么关注,直到最近几个月才看了一些 C++11 的新特性,今后几篇博客我都会写一些关于 C++11 的特性,算是记录一下自己学到的东西吧, ...

随机推荐

  1. Ubuntu 12.04更新源

    源地址:http://www.cnblogs.com/eastson/archive/2012/08/24/2654163.html 1.首先备份Ubuntu12.04源列表 sudo cp /etc ...

  2. sqlit使用要点之引入libsqlite3.dylib

    怎样引入libsqlite3.dylib? 在.h 或 .cpp文件里包括相应的头文件

  3. Datameer for Hadoop Solution

    Hadoop promises to become a ubiquitous framework for largescale business intelligence, but right now ...

  4. PHP实现插入排序算法

    插入排序(Insertion Sort),是一种较稳定.简单直观的排序算法.插入排序的工作原理,是通过构建有序序列,对于未排序的数据,在有序序列中从后向前扫描,找到合适的位置并将其插入.插入排序,在最 ...

  5. 自定义Annotation

    来源:http://blog.csdn.net/lifetragedy/article/details/7394910 概念篇 来看一个最简单的annotation示例 @Target(Element ...

  6. Android - 通过Intent启动Activity

    通过Intent启动Activity 本文地址: http://blog.csdn.net/caroline_wendy 为了动态关联Activity界面,使用Intent启动.能够灵活绑定. 在In ...

  7. web.xml的运行顺序

    整体上的顺序为 <context-param> <listener> <filter> <servlet> 往下依次运行. 当中,每一个类别内部都是按序 ...

  8. JAVA命令参数详解

    JAVA命令参数详解 JAVA命令详解 结构 说明 Java 和 OldJava JIT 选项 另请参阅 结构 java [ options ] class [ argument ... ] java ...

  9. Java命令参数说明

    Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令 JAVA_HOME"bin"java –option 来启动,-option为虚 ...

  10. git笔记之解决eclipse不能提交jar等文件的问题

    今天用git托管了一个java web项目,由于是web项目,所以要上传jar文件(此项目未使用maven管理),一直使用git commit and push,就是在server上看不到jar文件上 ...