关闭

c++ 11 多线线程系列-----------使用c++11 lambda创建线程

标签: c++多线程c++11多线程mutexc++ mutexc++ 11 多线线程系列
2575人阅读 评论(0) 收藏 举报
分类:

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

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

#include <thread>

#include <iostream>

 

void hello()

{

    std::cout << "Hello from thread " << std::endl;

}

 

int main()

{

    std::thread t1(hello);

    t1.join();

std::cout<<"Main Thread"<<std::endl;

    return 0;

}

运行结果:

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

 

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

#include <thread>

#include <iostream>

#include <vector>

 

int main()

{

    std::vector<std::thread> threads;

 

    for(int i = 0; i < 5; ++i){

        threads.push_back(std::thread([](){

            std::cout << "Hello from lamda thread " << std::this_thread::get_id() << std::endl;

        }));

    }

 

    for(auto& thread : threads){

        thread.join();

    }

 

    std::cout<<"Main Thread"<<"\t"<<std::this_thread::get_id()<<std::endl;

    return 0;

}

运行结果:

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

 

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

#include <thread>

#include <iostream>

#include <mutex>

using namespace std;

 

int main()

{

    std::mutex m;

    thread t1([&m]()

    {

        std::this_thread::sleep_for (chrono::seconds(10)); 

        for(int i=0;i<10;i++) 

         {     

            m.lock(); 

                cout <<  "In t1 ThreadID : " << std::this_thread::get_id() << ":" << i << endl;         

            m.unlock (); 

        } 

    } );

 

    thread t2([&m]() 

    {          

        std::this_thread::sleep_for (chrono::seconds(1)); 

        for(int i=0;i<10;i++) 

        {         

            m.lock (); 

                cout <<  "In t2 ThreadID : " << std::this_thread::get_id() << ":" << i << endl;         

            m.unlock(); 

        } 

    } ); 

    t1.join();     

    t2.join();     

 

    cout<<"Main Thread"<<endl;

 

    return 0;

}

运行结果:

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

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

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

#include <thread>

#include <iostream>

#include <vector>

#include <mutex>

 

struct Counter {

    std::mutex mutex;

    int value;

 

    Counter() : value(0) {}

 

    void increment(){

       // mutex.lock();                【1】表示没有使用锁

        ++value;

       // mutex.unlock();              【1】

    }

 

    void decrement(){

        mutex.lock();

        --value;

        mutex.unlock();

    }

};

 

int main(){

    Counter counter;

 

    std::vector<std::thread> threads;

 

    for(int i = 0; i < 5; ++i){

        threads.push_back(std::thread([&](){

            for(int i = 0; i < 10000; ++i){

                counter.increment();

            }

        }));

    }

 

    for(auto& thread : threads){

        thread.join();

    }

 

    std::cout << counter.value << std::endl;

 

    return 0;

}

运行结果:

【1】

运行结果:(使用了锁)

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

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

C++11多线程基本使用

C++11增加了线程及线程相关的累,很方便的支持了并发编程,使得编写的多线程程序的可移植性得到了很大的提高.
  • wrx1721267632
  • wrx1721267632
  • 2016-08-13 11:31
  • 2936

c++ 线程并发、任务队列、异步 任务封装和分发 lambda与任务 boost

在开发C++程序时,一般在吞吐量、并发、实时性上有较高的要求。设计C++程序时,总结起来可以从如下几点提高效率: 并发异步缓存 下面将我平常工作中遇到一些问题例举一二,其设计思想无非以上三...
  • brandohero
  • brandohero
  • 2016-02-01 21:59
  • 2488

boost和c++11创建线程的区别

C++11引入线程库,给广大的C++苦逼程序员带来了福音,之前项目中使用的是boost库,为了响应C++11的热情号召,决定最近的项目中就开始使用C++11线程库! 于是我很愉快的写出下面的...
  • lmb1612977696
  • lmb1612977696
  • 2017-10-30 15:21
  • 95

C++11/14--线程中使用Lambda函数

多线程中使用lambda 并发编程的不确定性多线程中使用lambda在本篇文章中,主要介绍lambda函数在多线程中的使用。 先从下面的例子开始吧:#include #include int ma...
  • y396397735
  • y396397735
  • 2017-12-25 23:54
  • 33

[C++11 并发编程] 12 使用条件变量创建线程间安全的队列

之前有一节中,我们使用mutex实现了一个线程间安全的堆栈。这一节,我们使用条件变量来实现一个线程间安全的队列。 标准库中的std::queue template > class queue { p...
  • yamingwu
  • yamingwu
  • 2015-08-26 21:28
  • 641

c++ 11 多线线程系列--------使用锁和条件变量的线程安全队列

哎哟,自己仔细体会咯,想要拿去用随便好了!!! #include #include #include #include #include #include #include #incl...
  • chenxun2009
  • chenxun2009
  • 2015-11-24 22:15
  • 1065

c++ 11 多线线程系列-----thread

一、与 C++11 多线程相关的头文件 C++11 新标准中引入了四个头文件来支持多线程编程,他们分别是 ,,,和。 :该头文主要声明了两个类, std::atomic 和 std::atomi...
  • chenxun2009
  • chenxun2009
  • 2015-11-11 20:19
  • 3793

c++ 11 多线线程系列----mutex

Mutex 又称互斥量,C++ 11中与 Mutex 相关的类(包括锁类型)和函数都声明在 头文件中,所以如果你需要使用 std::mutex,就必须包含 头文件。 头文件介绍 Mutex ...
  • chenxun2009
  • chenxun2009
  • 2015-11-11 23:42
  • 2083

c++ 11 多线线程系列-----thread

一、与 C++11 多线程相关的头文件地方 C++11 新标准中引入了四个头文件来支持多线程编程,他们分别是 ,,,和。 :该头文主要声明了两个类, std::atomic 和 s...
  • u010164190
  • u010164190
  • 2016-11-19 20:01
  • 110

c++ 11 多线线程系列-------- 一个最简单而且实用的线程池

至于什么是线程池,线程池是干神马的,大家自己网上查阅一下。 #include #include #include #include #include #include #inc...
  • chenxun2009
  • chenxun2009
  • 2015-11-24 22:52
  • 935
    个人资料
    • 访问:345365次
    • 积分:6696
    • 等级:
    • 排名:第4137名
    • 原创:315篇
    • 转载:40篇
    • 译文:0篇
    • 评论:60条
    博客专栏
    最新评论