C++ 基础学习六 —— 计算机中的乱序执行

本文详细介绍了计算机中的乱序执行现象,包括其允许的情况和内存模式的使用。接着,讨论了副作用在多线程编程中的影响,特别是对共享变量的修改。接着,讲解了信号量(binary_semaphore和counting_semaphore)在同步中的应用。最后,介绍了future库在任务链中的作用,特别是在生产者消费者问题中的实现。通过future,可以确保任务的异步执行并传递结果。
摘要由CSDN通过智能技术生成

计算机中的乱序执行

1. 一定会按正常顺序执行的情况

  • 对同一块内存进行访问,此时访问的顺序不会被编译器修改
  • 新定义的变量的值依赖于之前定义的变量,此时两个变量定义的顺序不会被编译器修改

2. 其他情况计算机会进行乱序执行

单线程情况下允许乱序进行,多线程情况下会出现问题

3. C++中的库中提供了6种内存模式用于多线程情况下 防止编译器的乱序进行

(1) memory_order_relaxed : 最放松的

(2)memory_order_consume:

​ 当客户使用,搭配release使用,被release进行赋值的变量y,获取的时候如果写成consume,那么所有与y有关的变量的赋值,一定会按顺序进行。

(3)memory_order_acquire: 用于获取资源

(4)memory_order_release:

一般用于生产者,当给一个变量y进行赋值的时候,只有自己将这个变量释放了,别人才可以去读,读的时候如果使用acquire来读,编译器会保证y之前被赋值的变量都在y之前被执行,相当于设置了内存屏障。

(5)memory_order_acq_rel

(6)memory_order_deq_cst

**好处:**不需要编译器设置内存屏障,morden c++开始就会有底层汇编的能力

副作用

1. 无副作用编程

存在一个函数,传一个参数x进去,里面进行一系列的运算,返回一个y。中间所有的过程都是在栈中进行修改的。

2. 有副作用编程

例如:在一个函数运行过程中,对全局变量进行了修改,或者在屏幕上输出了一些东西。此函数还有可能是类的成员方法,在此方法中如果对成员变量进行了修改,类的状态就会发生改变

3. 在多线程的情况下有副作用编程

在线程1运行的时候对成员变量进行了修改,此时如果再继续执行运行线程2,此时线程2拥有的就不是这个类的初始状态,而会受到线程1的影响。

信号量

1. binary_semaphore

定义:

可以当做事件来用,只有有信号和无信号两种状态,一次只能被一个线程所拥有

使用步骤:

(1)初始创建信号量,并且一开始将其置位成无信号状态

std::binary_semaphore sem(0)

(2)线程使用acquire()方法等待被唤醒

(3)主线程中使用release()方法,将信号量变成有信号状态。

2. counting_semaphore

定义:

一次可以被很多线程所持有,线程的数量由自己指定

使用步骤:

(1)创建信号量

指定一次可以进入的线程的最大数量,并在最开始将其置位成无信号状态:

std::binary_semaphore<8> sem(0);

(2)主线程中创建10个线程

并且这些线程全部调用acquire()方法等待被唤醒。但是主线程使用release(6)方法就只能随机启用6个线程。

future库

用于任务链 (即:任务A的执行必须依赖于任务B的返回值)

1. 例子:生产者消费者问题

(1)子线程作为消费者

参数是一个future,用这个future等待一个int型产品:std::future & fut

(2)子线程中使用get()方法,等待一个未来的future,返回一个result

(3)主线程作为生产者,做出一个承诺:std::promise prom

(4)用此承诺中的get_future()方法获取一个future

(5)主线程中将子线程创建出来,并将刚刚获取到的future作为参数传入

(6)主线程做出一些列的生产工作,最后生产完成后使用承诺中的set_value()方法,参数为刚刚生产出的产品

(7)此时产品就会被传入到子线程中,子线程就可以使用此产品做出一系列动作

(8)最后使用join()方法等待子线程静止。但是join只适用于等待没有返回值的线程的情况

2. 如果线程有返回值

(1)使用 async方法可以进行异步执行

**参数一:**可以选择是马上执行还是等一会执行 (即当消费者线程调用get()方法时,才开始执行)

**参数二:**执行的内容(可以放一个函数对象和lambda表达式

(2)生产者使用saync方法做生产工作,并返回一个future

(3)消费者使用future中的get()方法可以获取产品

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

L☆★

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值