配套视频课程已更新完毕,大家可通过以下两种方式观看视频讲解:
关注公众号:爱编程的大丙,或者进入大丙课堂学习。
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
局部链接多播地址:是为路由协议和其它用途保留的地址,只能用于局域网中,路由器是不会转发的地 ...
1. 广播的特点广播的UDP的特性之一,通过广播可以向子网中多台计算机发送消息,并且子网中所有的计算机都可以接收到发送方发送的消息,每个广播消息都包含一个特殊的IP地址,这个IP中子网内主机标志部分的二进制全部为1 (即点分十进制IP的最后一部分是255)。点分十进制的IP地址每一部分是1字节,最大值为255,比如:192.168.1.100
前两部分192.168表示当前网络是局域网
第三部分1表示局域网中的某一个网段,最大值为 255
第四部分100用于标记当前网段中的某一台主机,最大值为255
每个网段都有一个特殊的广播地址,即:192.168.xxx.255
广播分为两端,即数据发送端和数据接收端,通过广播的方式发送数据,发送端和接收端的关系是 1:N
发送广播消息的一端,通过广播地址,可以将消息同时发送到局域网的多台主机上(数据接收端)
在发送广播消息的时候,必须要把数据发送到广播地址上
广播只能在局域网内使用,广域网是无法使用UDP进行广播的
只要发送端在发送广播消息,数据接收端就能收到广播消息,消息的接收是无法拒绝的,除非将接收端的进程关闭,就接收不到了。
...
Linux
未读udp是一个面向无连接的,不安全的,报式传输层协议,udp的通信过程默认也是阻塞的。
UDP通信不需要建立连接 ,因此不需要进行connect()操作
UDP通信过程中,每次都需要指定数据接收端的IP和端口,和发快递差不多
UDP不对收到的数据进行排序,在UDP报文的首部中并没有关于数据顺序的信息
UDP对接收到的数据报不回复确认信息,发送端不知道数据是否被正确接收,也不会重发数据。
如果发生了数据丢失,不存在丢一半的情况,如果丢当前这个数据包就全部丢失了
1. 通信流程使用UDP进行通信,服务器和客户端的处理步骤比TCP要简单很多,并且两端是对等的 (通信的处理流程几乎是一样的),也就是说并没有严格意义上的客户端和服务器端。UDP的通信流程如下:
1.1 服务器端假设服务器端是接收数据的角色:
创建通信的套接字
12// 第二个参数是 SOCK_DGRAM, 第三个参数0表示使用报式协议中的udpint fd = socket(AF_INET, SOCK_DGRAM, 0);
使用通信的套接字和本地的IP和端口绑定,IP和端口需要转换为大端(可选)
1bin ...
Linux
未读1. 概述epoll 全称 eventpoll,是 linux 内核实现IO多路转接/复用(IO multiplexing)的一个实现。IO多路转接的意思是在一个操作里同时监听多个输入输出源,在其中一个或多个输入输出源可用的时候返回,然后对其的进行读写操作。epoll是select和poll的升级版,相较于这两个前辈,epoll改进了工作方式,因此它更加高效。
对于待检测集合select和poll是基于线性方式处理的,epoll是基于红黑树来管理待检测集合的。
select和poll每次都会线性扫描整个待检测集合,集合越大速度越慢,epoll使用的是回调机制,效率高,处理效率也不会随着检测集合的变大而下降
select和poll工作过程中存在内核/用户空间数据的频繁拷贝问题,在epoll中内核和用户区使用的是共享内存(基于mmap内存映射区实现),省去了不必要的内存拷贝。
程序猿需要对select和poll返回的集合进行判断才能知道哪些文件描述符是就绪的,通过epoll可以直接得到已就绪的文件描述符集合,无需再次检测
使用epoll没有最大文件描述符的限制,仅受系统中进程能 ...
Linux
未读1. poll函数poll的机制与select类似,与select在本质上没有多大差别,使用方法也类似,下面的是对于二者的对比:
内核对应文件描述符的检测也是以线性的方式进行轮询,根据描述符的状态进行处理
poll和select检测的文件描述符集合会在检测过程中频繁的进行用户区和内核区的拷贝,它的开销随着文件描述符数量的增加而线性增大,从而效率也会越来越低。
select检测的文件描述符个数上限是1024,poll没有最大文件描述符数量的限制
select可以跨平台使用,poll只能在Linux平台使用
poll函数的函数原型如下:
12345678910#include <poll.h>// 每个委托poll检测的fd都对应这样一个结构体struct pollfd { int fd; /* 委托内核检测的文件描述符 */ short events; /* 委托内核检测文件描述符的什么事件 */ short revents; /* 文件描述符实际发生的事件 -> 传出 */};struct p ...
1. 线程池的原理我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。
那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务呢?
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。
在各个编程语言的语种中都有线程池的概念,并且很多语言中直接提供了线程池,作为程序猿直接使用就可以了,下面给大家介绍一下线程池的实现原理:
线程池的组成主要分为3个部分,这三 ...
在进行桌面应用程序开发的时候, 假设应用程序在某些情况下需要处理比较复杂的逻辑, 如果只有一个线程去处理,就会导致窗口卡顿,无法处理用户的相关操作。这种情况下就需要使用多线程,其中一个线程处理窗口事件,其他线程进行逻辑运算,多个线程各司其职,不仅可以提高用户体验还可以提升程序的执行效率。
在qt中使用了多线程,有些事项是需要额外注意的:
默认的线程在Qt中称之为窗口线程,也叫主线程,负责窗口事件处理或者窗口控件数据的更新
子线程负责后台的业务逻辑处理,子线程中不能对窗口对象做任何操作,这些事情需要交给窗口线程处理
主线程和子线程之间如果要进行数据的传递,需要使用Qt中的信号槽机制
1. 线程类 QThreadQt中提供了一个线程类,通过这个类就可以创建子线程了,Qt中一共提供了两种创建子线程的方式,后边会依次介绍其使用方式。先来看一下这个类中提供的一些常用API函数:
1.1 常用共用成员函数123456789101112131415161718192021222324252627// QThread 类常用 API// 构造函数QThread::QThread(QObject * ...