配套视频课程已更新完毕,大家可通过以下两种方式观看视频讲解:
关注公众号:爱编程的大丙,或者进入大丙课堂学习。
1. std::futureC++11中增加的线程类,使得我们能够非常方便的创建和使用线程,但有时会有些不方便,比如需要获取线程返回的结果,就不能通过join()得到结果,只能通过一些额外手段获得,比如:定义一个全局变量,在子线程中赋值,在主线程中读这个变量的值,整个过程比较繁琐。C++提供的线程库中提供了一些类用于访问异步操作的结果。
那么,什么叫做异步呢?
我们去星巴克买咖啡,因为都是现磨的,所以需要等待,但是我们付完账后不会站在柜台前死等,而是去找个座位坐下来玩玩手机打发一下时间,当店员把咖啡磨好之后,就会通知我们过去取,这就叫做异步。
顾客(主线程)发起一个任务(子线程磨咖啡),磨咖啡的过程中顾客去做别的事情了,有两条时间线(异步)
顾客(主线程)发起一个任务(子线程磨咖啡),磨咖啡的过程中顾客没去做别的事情而是死等,这时就只有一条时间线(同步),此时效率相对较低。
因此多线程程序中的任务大都是异步的,主线程和子线程分别执行不同的任务,如果想要在主 ...
配套视频课程已更新完毕,大家可通过以下两种方式观看视频讲解:
关注公众号:爱编程的大丙,或者进入大丙课堂学习。
在某些特定情况下,某些函数只能在多线程环境下调用一次,比如:要初始化某个对象,而这个对象只能被初始化一次,就可以使用std::call_once()来保证函数在多线程环境下只能被调用一次。使用call_once()的时候,需要一个once_flag作为call_once()的传入参数,该函数的原型如下:
123// 定义于头文件 <mutex>template< class Callable, class... Args >void call_once( std::once_flag& flag, Callable&& f, Args&&... args );
flag:once_flag类型的对象,要保证这个对象能够被多个线程同时访问到
f:回调函数,可以传递一个有名函数地址,也可以指定一个匿名函数
args:作为实参传递给回调函数
多线程操作过程中,std::call_once()内部的 ...
配套视频课程已更新完毕,大家可通过以下两种方式观看视频讲解:
关注公众号:爱编程的大丙,或者进入大丙课堂学习。
C++11提供了一个原子类型std::atomic<T>,通过这个原子类型管理的内部变量就可以称之为原子变量,我们可以给原子类型指定bool、char、int、long、指针等类型作为模板参数(不支持浮点类型和复合类型)。
原子指的是一系列不可被CPU上下文交换的机器指令,这些指令组合在一起就形成了原子操作。在多核CPU下,当某个CPU核心开始运行原子操作时,会先暂停其它CPU内核对内存的操作,以保证原子操作不会被其它CPU内核所干扰。
由于原子操作是通过指令提供的支持,因此它的性能相比锁和消息传递会好很多。相比较于锁而言,原子类型不需要开发者处理加锁和释放锁的问题,同时支持修改,读取等操作,还具备较高的并发性能,几乎所有的语言都支持原子类型。
可以看出原子类型是无锁类型,但是无锁不代表无需等待,因为原子类型内部使用了CAS循环,当大量的冲突发生时,该等待还是得等待!但是总归比锁要好。
C++11内置了整形的原子变量,这样就可以更方便的使用原子变量了。 ...
配套视频课程已更新完毕,大家可通过以下两种方式观看视频讲解:
关注公众号:爱编程的大丙,或者进入大丙课堂学习。
条件变量是C++11提供的另外一种用于等待的同步机制,它能阻塞一个或多个线程,直到收到另外一个线程发出的通知或者超时时,才会唤醒当前阻塞的线程。条件变量需要和互斥量配合起来使用,C++11提供了两种条件变量:
condition_variable:需要配合std::unique_lock<std::mutex>进行wait操作,也就是阻塞线程的操作。
condition_variable_any:可以和任意带有lock()、unlock()语义的mutex搭配使用,也就是说有四种:
std::mutex:独占的非递归互斥锁
std::timed_mutex:带超时的独占非递归互斥锁
std::recursive_mutex:不带超时功能的递归互斥锁
std::recursive_timed_mutex:带超时的递归互斥锁
条件变量通常用于生产者和消费者模型,大致使用过程如下:
拥有条件变量的线程获取互斥量
循环检查某个条件,如果条件不满足 ...
配套视频课程已更新完毕,大家可通过以下两种方式观看视频讲解:
关注公众号:爱编程的大丙,或者进入大丙课堂学习。
进行多线程编程,如果多个线程需要对同一块内存进行操作,比如:同时读、同时写、同时读写对于后两种情况来说,如果不做任何的人为干涉就会出现各种各样的错误数据。这是因为线程在运行的时候需要先得到CPU时间片,时间片用完之后需要放弃已获得的CPU资源,就这样线程频繁地在就绪态和运行态之间切换,更复杂一点还可以在就绪态、运行态、挂起态之间切换,这样就会导致线程的执行顺序并不是有序的,而是随机的混乱的,就如同下图中的这个例子一样,理想很丰满现实却很残酷。
解决多线程数据混乱的方案就是进行线程同步,最常用的就是互斥锁,在C++11中一共提供了四种互斥锁:
std::mutex:独占的互斥锁,不能递归使用
std::timed_mutex:带超时的独占互斥锁,不能递归使用
std::recursive_mutex:递归互斥锁,不带超时功能
std::recursive_timed_mutex:带超时的递归互斥锁
互斥锁在有些资料中也被称之为互斥量,二者是一个东西。
如 ...
配套视频课程已更新完毕,大家可通过以下两种方式观看视频讲解:
关注公众号:爱编程的大丙,或者进入大丙课堂学习。
在C++11中不仅添加了线程类,还添加了一个关于线程的命名空间std::this_thread,在这个命名空间中提供了四个公共的成员函数,通过这些成员函数就可以对当前线程进行相关的操作了。
1. get_id()调用命名空间std::this_thread中的get_id()方法可以得到当前线程的线程ID,函数原型如下:
1thread::id get_id() noexcept;
关于函数使用对应的示例代码如下:
123456789101112131415#include <iostream>#include <thread>using namespace std;void func(){ cout << "子线程: " << this_thread::get_id() << endl;}int main(){ cout << ...
配套视频课程已更新完毕,大家可通过以下两种方式观看视频讲解:
关注公众号:爱编程的大丙,或者进入大丙课堂学习。
C++11之前,C++语言没有对并发编程提供语言级别的支持,这使得我们在编写可移植的并发程序时,存在诸多的不便。现在C++11中增加了线程以及线程相关的类,很方便地支持了并发编程,使得编写的多线程程序的可移植性得到了很大的提高。
C++11中提供的线程类叫做std::thread,基于这个类创建一个新的线程非常的简单,只需要提供线程函数或者函数对象即可,并且可以同时指定线程函数的参数。我们首先来了解一下这个类提供的一些常用API:
1. 构造函数123456789// ①thread() noexcept;// ②thread( thread&& other ) noexcept;// ③template< class Function, class... Args >explicit thread( Function&& f, Args&&... args );// ④thread( const t ...
配套视频课程已更新完毕,大家可通过以下两种方式观看视频讲解:
关注公众号:爱编程的大丙,或者进入大丙课堂学习。
在C++11中提供了专门的类型转换函数,程序猿可以非常方便的使用它们进行数值类型和字符串类型之间的转换。
1. 数值转换为字符串使用to_string()方法可以非常方便地将各种数值类型转换为字符串类型,这是一个重载函,函数声明位于头文件<string>中,函数原型如下:
12345678910// 头文件 <string>string to_string (int val);string to_string (long val);string to_string (long long val);string to_string (unsigned val);string to_string (unsigned long val);string to_string (unsigned long long val);string to_string (float val);string to_string (double val);str ...
配套视频课程已更新完毕,大家可通过以下两种方式观看视频讲解:
关注公众号:爱编程的大丙,或者进入大丙课堂学习。
C++11中提供了日期和时间相关的库chrono,通过chrono库可以很方便地处理日期和时间,为程序的开发提供了便利。chrono库主要包含三种类型的类:时间间隔duration、时钟clocks、时间点time point。
1. 时间间隔duration1.1 常用类成员duration表示一段时间间隔,用来记录时间长度,可以表示几秒、几分钟、几个小时的时间间隔。duration的原型如下:
12345// 定义于头文件 <chrono>template< class Rep, class Period = std::ratio<1>> class duration;
Rep:这是一个数值类型,表示时钟数(周期)的类型(默认为整形)。若 Rep 是浮点数,则 duration 能使用小数描述时钟周期的数目。
Period:表示时钟的周期,它的原型如下:
12345// 定义于头文件 <ratio ...
Linux
未读1. 组播的特点组播也可以称之为多播这也是UDP的特性之一。组播是主机间一对多的通讯模式,是一种允许一个或多个组播源发送同一报文到多个接收者的技术。组播源将一份报文发送到特定的组播地址,组播地址不同于单播地址,它并不属于特定某个主机,而是属于一组主机。一个组播地址表示一个群组,需要接收组播报文的接收者都加入这个群组。
广播只能在局域网访问内使用,组播既可以在局域网中使用,也可以用于广域网
在发送广播消息的时候,连接到局域网的客户端不管想不想都会接收到广播数据,组播可以控制发送端的消息能够被哪些接收端接收,更灵活和人性化。
广播使用的是广播地址,组播需要使用组播地址。
广播和组播属性默认都是关闭的,如果使用需要通过setsockopt()函数进行设置。
组播需要使用组播地址,在 IPv4 中它的范围从 224.0.0.0 到 239.255.255.255,并被划分为局部链接多播地址、预留多播地址和管理权限多播地址三类:
IP地址
说明
224.0.0.0~224.0.0.255
局部链接多播地址:是为路由协议和其它用途保留的地址,只能用于局域网中,路由器是不会转发的地 ...