C++11的简单学习及生产者消费者示例

lambda

  • 格式
    [捕获列表](参数列表) -> 返回类型 {
    // 函数体
    }
  • 值捕获
void TestLambda()
{
    //1.值捕获,可以写成[=],被捕获的变量在lambda表达式创建时拷贝,而非调用时才拷贝
    int nVal = 1;
    //auto copyValue = [nVal]  //方式1
    auto copyValue = [=]       //方式2
    {
        return nVal;
    };

    nVal = 100;
    auto nVal2 = copyValue();
    std::cout << "nVal=" << nVal << ",nVal2=" << nVal2 << endl; //输出nVal=100,nVal2=1
}
  • 引用捕获
void TestLambda()
{
    int nVal = 1;
    //2.引用捕获,可以写成[&],被捕获的变量保存的是引用
    //auto copyValue2 = [&nVal] //方式1
    auto copyValue2 = [&] //方式2
    {
        return nVal;
    };
    nVal = 100;
    auto nVal3= copyValue2();
    std::cout << "nVal=" << nVal << ",nVal3=" << nVal3 << endl; //输出nVal=100,nVal3=100

}

function

头文件:#include <functional>

int Add(int a, int b)
{
    return a + b;
}

void TestFunction()
{
    //int(int, int) 分别对应返回类型和输入参数
    std::function<int(int, int)> func = Add;
    cout << func(1, 2) << endl;      // 3
}

bind/placeholders

int Add(int i, int j)
{
    return i + j;
}
void TestBind()
{
	//std::placeholders::_1表示占位符
    auto bindAdd = std::bind(Add, std::placeholders::_1, 10);
    std::cout << bindAdd(10) << endl; //输出20
    std::cout << bindAdd(10, 15) << endl; //输出20,因为第二个参数固定为10
}

regex

正则表达式:#include <regex>

void TestRegex()
{
    string strFileNames[] = { "abc.txt", "def.txt", "Abc.txt","Def.txt" };
    regex txtRegex("([a-z]+)\\.txt");
    smatch matchResult;
    for (const auto &strFileName : strFileNames)
    {
        cout << strFileName << ":" << regex_match(strFileName, txtRegex) << endl;
        if (regex_match(strFileName, matchResult,txtRegex))
        {
            if (matchResult.size() == 2)
            {
                //第一个元素匹配整个字符串
                cout << "matchResult[0] = " << matchResult[0].str() << endl;
                //第二个元素匹配第一个括号表达式
                cout << "matchResult[1] = " << matchResult[1].str() << endl;
            }
        }
    }
}

输出
在这里插入图片描述

thread&mutex&condition_variable

Factory.h

#pragma once
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
using namespace std;
class CFactory
{
public:
	CFactory();
	void Run();
private:
	void Produce();
	void Consume();
private:
	mutex m_mutex;
	condition_variable m_cond;
	queue<int> m_nQueue;
	bool m_bDone;
	bool m_bNotify;
};

Factory.cpp

#include "Factory.h"
#include <iostream>
#include <chrono>
using namespace std;

CFactory::CFactory()
{
    m_bDone = false;
    m_bNotify = false;
}

void CFactory::Produce()
{
    for (size_t i = 0; i < 4; i++)
    {
        this_thread::sleep_for(chrono::seconds(1));
        unique_lock <mutex> lockGuard(m_mutex);
        cout << "Produce thread:" << this_thread::get_id() << endl;
        m_nQueue.push(i);
        m_bNotify = true;
        m_cond.notify_one();
        cout << "Produce notify " << "i:" << i << endl;
    }
    unique_lock <mutex> lockGuard(m_mutex);
    m_bDone = true;
    m_cond.notify_all();
    cout << "Produce done!" << endl;
}

void CFactory::Consume()
{
    unique_lock<mutex> lockGuard(m_mutex);
    while (!m_bDone) {
        cout << "Consume thread:" << this_thread::get_id() << endl;
        while (!m_bNotify && !m_bDone)
        {
            cout << "Consume thread:" << this_thread::get_id() << ",Consume wait..." << endl;
            m_cond.wait(lockGuard);
        }
        while (!m_nQueue.empty())
        {
            cout << "Consume thread:" << this_thread::get_id() << ",Consume " << "i:" << m_nQueue.front() << endl;
            m_nQueue.pop();
        }
        m_bNotify = false;
    } 
    cout << "Consume thread:" << this_thread::get_id() << ",Consume done!" << endl;
}

void CFactory::Run()
{
    for (size_t i = 0; i < 2; i++)
    {
        thread consume(&CFactory::Consume, this);
        consume.detach();
    }

    this_thread::sleep_for(chrono::seconds(5));
    thread produce(&CFactory::Produce, this);
    produce.detach();
}

    CFactory factory;
    factory.Run();
    this_thread::sleep_for(chrono::seconds(50));

输出
在这里插入图片描述
条件变量:
主要是解决死锁。比如,线程可能需要等待某个条件为真才能继续执行,而一个忙等待循环中可能会导致其他线程都无法进入临界区使得条件为真时,就会发生死锁。条件变量主要就是唤醒等待线程从而避免死锁。
wait说明:
1、执行wait等待时会原子性的释放mutex,并使得线程执行暂停
2、当其他线程通过notify_one或notify_all唤醒时,重新获得mutex

猜你喜欢

转载自blog.csdn.net/weixin_43628270/article/details/107701349