- 博客(91)
- 资源 (7)
- 收藏
- 关注
原创 Qt中多线程使用案列
因此,QT 的线程开启就是在创建线程,只不过其中含有事件循环机制。另外对于自定义类型,必须指定队列连接。上处代码运行可以看出,QThread 中,每次调用start() 时 ,都会改变线程ID。
2023-12-20 19:18:52
704
原创 Qt 中model/View 架构 详解,以及案例实现相薄功能
fill:#333;color:#333;color:#333;fill:none;**QAbstractItemDelegate:**中含有2个纯虚函数编号 01 函数Model 项数据在View进行绘画的函数,具体绘画功能在此实现。编号02 函数Model 项数据在View 进行绘画的区域大小。return;reset();
2023-10-31 10:37:36
1437
原创 __declspec(dllexport)和__declspec(dllimport)以及QT中public: static struct QMetaObject const xxx:staticMe
修复public: static struct QMetaObject const xxx:staticMetaObject
2022-09-16 11:20:41
1637
1
原创 C++多线程学习
std::thread: 用于创建一个执行的线程实列,所以它是一切并发编程的基础,使用时需要包含****头文件,它提供了很多基本的线程操作,列如:get_id()来获取所创建线程ID,使用jion()来加入一个线程等等。互斥量与临界区我们在操作系统、亦或是数据库的相关知识中已经了解过了有关并发技术的基本知识,mutex 就是其中的核心之一。 C++11 引入了 mutex 相关的类,其所有相关的函数都放在 头文件中。std::mutex 是 C++11 中最基本的 mutex 类,通过实例化 std
2022-06-27 11:30:56
407
原创 QtWidget实现图片放大器功能
使用重写QtWidget 实现图片放大器功能话不多说直接上代码功能描述:该控件可同时使用两张图片进行比较,支持拖动以及放大等功能插入链接与图片话不多说直接上代码功能描述:该控件可同时使用两张图片进行比较,支持拖动以及放大等功能#pragma once#include <QWidget>#include "CImagePlayer.h"#include "CGraphicsPixmapItem.h"#include "CGraphicsScene.h"#include "CGra
2022-05-31 18:06:11
823
1
原创 OpenGL入门
OpenGL入门一 OpenGL概念**概念:**一般它被认为是一个API(Application Programming Interface, 应用程序编程接口),包含了一系列可以操作图形、图像的函数。然而,OpenGL本身并不是一个API,它仅仅是一个由Khronos组织制定并维护的规范(Specification)。二 核心模式与立即渲染模式早期的OpenGL使用立即渲染模式(Immediate mode,也就是固定渲染管线),这个模式下绘制图形很方便。OpenGL的大多数功能都被库隐藏
2022-02-20 21:24:24
495
原创 编写一个使用锁的线程安全查询表
6.3 基于锁设计更加复杂的数据结构栈和队列都很简单:接口相对固定,并且它们应用于比较特殊的情况。并不是所有数据结构都像它们一样简单;大多数数据结构支持更加多样化的操作。原则上,这将增大并行的可能性,但是也让对数据保护变得更加困难,因为要考虑对所有能访问到的部分。当为了并发访问对数据结构进行设计时,这一系列原有的操作,就变得越发重要,需要重点处理。先来看看,在查询表的设计中,所遇到的一些问题。6.3.1 编写一个使用锁的线程安全查询表查询表或字典是一种类型的值(键值)和另一种类型的值进行关联(映射的
2022-01-16 11:03:43
3858
原创 基于锁的并发数据结构
6.2 基于锁的并发数据结构基于锁的并发数据结构设计,需要确保访问线程持有锁的时间最短。对于只有一个互斥量的数据结构来说,这十分困难。需要保证数据不被锁之外的操作所访问到,并且还要保证不会在固有结构上产生条件竞争(如第3章所述)。当你使用多个互斥量来保护数据结构中不同的区域时,问题会暴露的更加明显,当操作需要获取多个互斥锁时,就有可能产生死锁。所以,在设计时,使用多个互斥量时需要格外小心。在本节中,你将使用6.1.1节中的指导建议,来设计一些简单的数据结构——使用互斥量和锁的方式来保护数据。每一个例子中
2022-01-16 11:03:10
500
原创 同步操作和强制排序
5.3 同步操作和强制排序假设你有两个线程,一个向数据结构中填充数据,另一个读取数据结构中的数据。为了避免恶性条件竞争,第一个线程设置一个标志,用来表明数据已经准备就绪,并且第二个线程在这个标志设置前不能读取数据。下面的程序清单就是这样的情况。清单5.2 不同线程对数据的读写#include <vector>#include <atomic>#include <iostream>std::vector<int> data;std::atomic
2022-01-16 11:00:42
760
原创 C++`中的原子操作和原子类型
5.2 C++中的原子操作和原子类型原子操作 是个不可分割的操作。在系统的所有线程中,你是不可能观察到原子操作完成了一半这种情况的;它要么就是做了,要么就是没做,只有这两种可能。如果从对象读取值的加载操作是 原子 的,而且对这个对象的所有修改操作也是 原子 的,那么加载操作得到的值要么是对象的初始值,要么是某次修改操作存入的值。另一方面,非原子操作可能会被另一个线程观察到只完成一半。如果这个操作是一个存储操作,那么其他线程看到的值,可能既不是存储前的值,也不是存储的值,而是别的什么值。如果这
2022-01-16 11:00:05
6905
原创 【无标题】
5.1 内存模型基础这里从两方面来讲内存模型:一方面是基本结构,这与事务在内存中是怎样布局的有关;另一方面就是并发。对于并发基本结构很重要,特别是在低层原子操作。所以我将会从基本结构讲起。C++中它与所有的对象和内存位置有关。5.1.1 对象和内存位置在一个C++程序中的所有数据都是由对象(objects)构成。这不是说你可以创建一个int的衍生类,或者是基本类型中存在有成员函数,或是像在Smalltalk和Ruby语言下讨论程序那样——“一切都是对象”。“对象”仅仅是对C++数据构建块的一个声明。C
2022-01-16 10:59:18
421
2
原创 使用同步操作简化代码
4.4 使用同步操作简化代码同步工具的使用在本章称为构建块,你可以之关注那些需要同步的操作,而非具体使用的机制。当需要为程序的并发时,这是一种可以帮助你简化你的代码的方式,提供更多的函数化的方法。比起在多个线程间直接共享数据,每个任务拥有自己的数据会应该会更好,并且结果可以对其他线程进行广播,这就需要使用“期望”来完成了。4.4.1 使用“期望”的函数化编程术语函数化编程(functional programming)引用于一种编程方式,这种方式中的函数结果只依赖于传入函数的参数,并不依赖外部状态。当
2022-01-16 10:57:36
250
原创 限定等待时间
4.3 限定等待时间之前介绍过的所有阻塞调用,将会阻塞一段不确定的时间,将线程挂起直到等待的事件发生。在很多情况下,这样的方式很不错,但是在其他一些情况下,你就需要限制一下线程等待的时间了。这允许你发送一些类似“我还存活”的信息,无论是对交互式用户,或是其他进程,亦或当用户放弃等待,你可以按下“取消”键直接终止等待。介绍两种可能是你希望指定的超时方式:一种是“时延”的超时方式,另一种是“绝对”超时方式。第一种方式,需要指定一段时间(例如,30毫秒);第二种方式,就是指定一个时间点(例如,协调世界时[UT
2022-01-16 10:56:36
355
原创 使用期望等待一次性事件
4.2 使用期望等待一次性事件假设你乘飞机去国外度假。当你到达机场,并且办理完各种登机手续后,你还需要等待机场广播通知你登机,可能要等很多个小时。你可能会在候机室里面找一些事情来打发时间,比如:读书,上网,或者来一杯价格不菲的机场咖啡,不过从根本上来说你就在等待一件事情:机场广播能够登机的时间。给定的飞机班次再之后没有可参考性;当你在再次度假的时候,你可能会等待另一班飞机。C++标准库模型将这种一次性事件称为期望(future)。当一个线程需要等待一个特定的一次性事件时,在某种程度上来说它就需要知道这个
2022-01-16 10:55:30
305
原创 等待一个事件或其他条件
4.1 等待一个事件或其他条件假设你在旅游,而且正在一辆在夜间运行的火车上。在夜间,如何在正确的站点下车呢?一种方法是整晚都要醒着,然后注意到了哪一站。这样,你就不会错过你要到达的站点,但是这样会让你感到很疲倦。另外,你可以看一下时间表,估计一下火车到达目的地的时间,然后在一个稍早的时间点上设置闹铃,然后你就可以安心的睡会了。这个方法听起来也很不错,也没有错过你要下车的站点,但是当火车晚点的时候,你就要被过早的叫醒了。当然,闹钟的电池也可能会没电了,并导致你睡过站。理想的方式是,无论是早或晚,只要当火车到
2022-01-16 10:53:56
280
原创 等待一个事件或其他条件
4.1 等待一个事件或其他条件假设你在旅游,而且正在一辆在夜间运行的火车上。在夜间,如何在正确的站点下车呢?一种方法是整晚都要醒着,然后注意到了哪一站。这样,你就不会错过你要到达的站点,但是这样会让你感到很疲倦。另外,你可以看一下时间表,估计一下火车到达目的地的时间,然后在一个稍早的时间点上设置闹铃,然后你就可以安心的睡会了。这个方法听起来也很不错,也没有错过你要下车的站点,但是当火车晚点的时候,你就要被过早的叫醒了。当然,闹钟的电池也可能会没电了,并导致你睡过站。理想的方式是,无论是早或晚,只要当火车到
2022-01-14 16:14:07
88
原创 保护共享数据的替代设施
3.3 保护共享数据的替代设施互斥量是最通用的机制,但其并非保护共享数据的唯一方式。这里有很多替代方式可以在特定情况下,提供更加合适的保护。一个特别极端(但十分常见)的情况就是,共享数据在并发访问和初始化时(都需要保护),但是之后需要进行隐式同步。这可能是因为数据作为只读方式创建,所以没有同步问题;或者因为必要的保护作为对数据操作的一部分,所以隐式的执行。任何情况下,数据初始化后锁住一个互斥量,纯粹是为了保护其初始化过程(这是没有必要的),并且这会给性能带来不必要的冲击。出于以上的原因,C++标准提供了
2022-01-14 16:13:28
239
原创 共享数据带来的问题
3.1 共享数据带来的问题当涉及到共享数据时,问题很可能是因为共享数据修改所导致。如果共享数据是只读的,那么只读操作不会影响到数据,更不会涉及对数据的修改,所以所有线程都会获得同样的数据。但是,当一个或多个线程要修改共享数据时,就会产生很多麻烦。这种情况下,就必须小心谨慎,才能确保一切所有线程都工作正常。不变量(invariants)的概念对程序员们编写的程序会有一定的帮助——对于特殊结构体的描述;比如,“变量包含列表中的项数”。不变量通常会在一次更新中被破坏,特别是比较复杂的数据结构,或者一次更新就要
2022-01-14 16:11:12
1485
原创 标识线程获取
2.5 标识线程线程标识类型是std::thread::id,可以通过两种方式进行检索。第一种,可以通过调用std::thread对象的成员函数get_id()来直接获取。如果std::thread对象没有与任何执行线程相关联,get_id()将返回std::thread::type默认构造值,这个值表示“无线程”。第二种,当前线程中调用std::this_thread::get_id()(这个函数定义在<thread>头文件中)也可以获得线程标识。std::thread::id对象可以自由
2022-01-14 16:09:24
1002
原创 运行时决定线程数量
2.4 运行时决定线程数量std::thread::hardware_concurrency()在新版C++标准库中是一个很有用的函数。这个函数将返回能同时并发在一个程序中的线程数量。例如,多核系统中,返回值可以是CPU核芯的数量。返回值也仅仅是一个提示,当系统信息无法获取时,函数也会返回0。但是,这也无法掩盖这个函数对启动线程数量的帮助。清单2.8实现了一个并行版的std::accumulate。代码中将整体工作拆分成小任务交给每个线程去做,其中设置最小任务数,是为了避免产生太多的线程。程序可能会在操
2022-01-14 16:08:31
274
1
C++种设计模式 装饰模式.rar
2020-06-14
C++策略模式二.rar
2020-06-11
简单工厂模式Demo-1.rar
2020-06-11
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人