美文网首页
C++ 线程、智能指针、11&14特性

C++ 线程、智能指针、11&14特性

作者: Itachi001 | 来源:发表于2021-09-13 17:09 被阅读0次

C++11线程

线程,有时被称为轻量进程,是程序执行的最小单元。

#include <thread>

void task(int i) {
    cout << "task:" << i << endl;
}

thread t1(task,100);
//等待线程结束再继续执行
t1.join();

POSIX线程

32位的动态库拷贝到windows/syswow64目录
64位的动态库拷贝到windows/system32目录

#include <pthread.h>
void *pthreadTask(void* args) {
    int* i = static_cast<int*>(args);
    cout << "posix线程:" << *i << endl;
    return 0;
}
pthread_t pid;
int pi = 100;
pthread_create(&pid, 0, pthreadTask, &pi);
//等待线程的结束
pthread_join(pid,0);

线程属性

线程具有属性,用 pthread_attr_t 表示

pthread_attr_t attr;
//初始化 attr中为操作系统实现支持的线程所有属性的默认值
pthread_attr_init(&attr);
pthread_attr_destroy(&attr);

分离线程

线程创建默认是非分离的,当pthread_join()函数返回时,创建的线程终止,释放自己占用的系统资源
分离线程不能被其他线程等待,pthread_join无效,线程自己玩自己的。

//设置是否为分离线程
//PTHREAD_CREATE_DETACHED 分离
//PTHREAD_CREATE_JOINABLE 非分离
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

调度策略与优先级

Windows 无法设置成功

//设置调度策略 
//返回0 设置成功
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
// SCHED_FIFO 
//  实时调度策略,先到先服务 一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃。
// SCHED_RR
//  实时调度策略,时间轮转 系统分配一个时间段,在时间段内执行本线程


//设置优先级
//获得对应策略的最小、最大优先级
int max = sched_get_priority_max(SCHED_FIFO);
int min = sched_get_priority_min(SCHED_FIFO);
sched_param param;
param.sched_priority = max;
pthread_attr_setschedparam(&attr, &param);

线程同步

多线程同时读写同一份共享资源的时候,可能会引起冲突。需要引入线程“同步”机制,即各位线程之间有序地对共享资源进行操作。

#pragma once
#include <queue>
using namespace std;

template <class T>
class SafeQueue {
public:
    SafeQueue() {
        pthread_mutex_init(&mutex,0);
        pthread_cond_init(&cond, 0);
    }
    ~SafeQueue() {
        pthread_mutex_destory(&mutex);
        pthread_cond_destory(&cond);
    }
    void enqueue(T t) {
        pthread_mutex_lock(&mutex);
        q.push(t);
        //发出信号 通知挂起线程
        //由系统唤醒一个线程
        //pthread_cond_signal(&cond);
        // 广播 对应多个消费者的时候 多个线程等待唤醒所有
        pthread_cond_broadcast(&cond);
        pthread_mutex_unlock(&mutex);
    }
    int dequeue(T& t) {
        pthread_mutex_lock(&mutex);
        //可能被意外唤醒 所以while循环
        while (q.empty())
        {
            pthread_cond_wait(&cond, &mutex);
        }
        t = q.front();
        q.pop();
        pthread_mutex_unlock(&mutex);
        return 1;
    }

private:
    queue<T> q;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
};
#include "lsn6_example.h"
#include <thread>
#include <pthread.h>

using namespace std;
#include "safe_queue.h"

SafeQueue<int> q;

void *get(void* args) {
    while (1) {
        int i;
        q.dequeue(i);
        cout << "消费:"<< i << endl;
    }
    return 0;
}
void *put(void* args) {
    while (1)
    {
        int i;
        cin >> i;
        q.enqueue(i);
    }
    return 0;
}
int main()
{
    pthread_t pid1, pid2;
    pthread_create(&pid1, 0, get, &q);
    pthread_create(&pid2, 0, put, &q);
    pthread_join(pid2,0);
    system("pause");
    return 0;
}

智能指针

自C++11起,C++标准库提供了两大类型的智能指针

shared_ptr

  1. 操作引用计数实现共享式拥有的概念。多个智能指针可以指向相同的对象,这个对象和其相关资源会在最后一个被销毁时释放。
  2. 虽然使用shared_ptr能够非常方便的为我们自动释放对象,但是还是会出现一些问题。最典型的就是循环引用问题。

weak_ptr

  1. weak_ptr是为配合shared_ptr而引入的一种智能指针。主要用于观测资源的引用情况。
  2. 它的构造和析构不会引起引用记数的增加或减少。没有重载*和->但可以使用lock获得一个可用的shared_ptr对象。
  3. 配合shared_ptr解决循环引用问题
class B;
class A {
public:
    ~A() {
        cout << "释放A" << endl;
    }
    weak_ptr<B> b;
};
class B {
public:
    ~B() {
        cout << "释放B" << endl;
    }
    weak_ptr<A> a;
};

void test() {
    //自动释放
    shared_ptr<A> a(new A()); //A引用计数为1
    shared_ptr<B> b(new B()); //B引用计数为1

    a->b = b;           //weak_ptr 引用计数不增加
    b->a = a;           //weak_ptr 引用计数不增加
    //退出方法,A B释放
}

weak_ptr 提供expired 方法等价于 use_count == 0,当expired为true时,lock返回一个存储空指针的shared_ptr

unique_ptr

实现独占式引用,保证同一时间只有一个智能指针指向内部对象。

unique_ptr<A> a(new A());

auto_ptr已经不推荐使用
自定义智能指针(略...)

部分C++11、14特性

nullptr

nullptr 出现的目的是为了替代 NULL。 C++11之前直接将NULL定义为 0。

void test(int* i){
    
}
void test(int i){
    
}
//现在调用哪一个test? test(int)
test(NULL);
//调用test(int* i)
test(nullptr); 

类型推导

C++11 重新定义了auto 和 decltype 这两个关键字实现了类型推导,让编译器来操心变量的类型。

auto i = 5;             // i 被推导为 int
auto p = new auto(10) // arr 被推导为 int *
//但是auto不能作用在数组上
auto arr1[10] = { 0 }; //错误
auto arr2= {0}; //正确
typeid(arr2).name() //获得类型名为 initializer_list(后续介绍)
// int  j
decltype(i) j = 10;

基于范围的 for 循环

实际上就是foreach

vector<int> vec = { 1,2,3,4,5 };
//配合auto使用
for(auto i : vec)
{
    cout << i << endl;
}

Lambda

匿名函数,即没有函数名的函数
完整形式:[捕获外部变量列表 ] (参数列表) mutable exception->返回类型 { 函数体 }
mutable:在外部变量列表以值来捕获时,无法修改变量的值,加上mutable表示可修改(不会影响外部变量)

auto i = 5;
// [&] 表示外部变量都以引用的形式在lambda中使用,函数内部修改i的值会影响外部
// 这里的 -> auto 自动推导在c++11不支持,c++14中对auto进行了扩展
thread t1([&] () -> auto {
    i = 100;
    cout << "线程:" << i  << endl;
});
_sleep(10);
cout << i << endl;
捕获形式 说明
[] 不捕获任何外部变量
[i, …] 以值得形式捕获指定的多个外部变量(用逗号分隔);如果引用捕获,需要显示声明&
[this] 以值的形式捕获this指针
[=] 以值的形式捕获所有外部变量
[&] 以引用形式捕获所有外部变量
[=, &x] 变量x以引用形式捕获,其余变量以传值形式捕获
[&, x] 变量x以值的形式捕获,其余变量以引用形式捕获

相关文章

  • C++ 线程、智能指针、11&14特性

    C++11线程 线程,有时被称为轻量进程,是程序执行的最小单元。 POSIX线程 32位的动态库拷贝到window...

  • C++线程与智能指针

    C++线程与智能指针 [TOC] 线程 线程,有时被称为轻量进程,是程序执行的最小单元。 C++11线程 POSI...

  • C++知识点

    C++基本方法: C++ memcpy C++基本特性: C++引用(vs指针) C++指针 C++封装: 将...

  • 技能

    C++ C++特性 C++11 多态和继承 构造函数 析构函数 手写代码实现string类 手写代码实现智能指针 ...

  • C++研发工程师笔试题/面试题(1-10)

    1. (1) 简述智能指针的原理;(2)c++中常用的智能指针有哪些?(3)实现一个简单的智能指针。 简述智能指针...

  • C++ 智能指针

    C++智能指针[https://zhuanlan.zhihu.com/p/54078587] C++11中智能指针...

  • c++智能指针用法

    智能指针是什么 智能指针是c++中有四个智能指针:auto_ptr、shared_ptr、weak_ptr、uni...

  • 阿里巴巴面试题基础篇 C++基础篇(二)

    ● 请你来说一下C++中的智能指针参考回答:C++里面的四个智能指针: auto_ptr, shared_ptr,...

  • C++线程与智能指针

    线程 线程,有时被称为轻量进程,是程序执行的最小单元。 C++11线程 POSIX线程 POSIX 可移植操作系统...

  • Android智能指针分析

    Android智能指针分析总结 什么是智能指针 C++ 指针需要手动释放,否则会造成内存泄露,但是如果项目工程比较...

网友评论

      本文标题:C++ 线程、智能指针、11&14特性

      本文链接:https://www.haomeiwen.com/subject/soyfgltx.html