CSAPP-note-1
Floating Point
Floating Point Representation
Normalized Values
Numerical Form:
(−1)s∗M∗2E(-1)^s*M*2^E
(−1)s∗M∗2E
S is a sign bit, it determines whether number is negative or positive.
Significand M normally a fractional value in range [1.0,2.0).
E weigths value by power of 2.
1234Single precision: 32 bitss:1 exp:8-bits frac:23-bitsDouble precision: 64 bitss:1 exp:11-bits frac:52-bits
E = Exp - Bias
Exp: unsigned value of exp field.
Bias = 2k−1−12^{k-1}-12k−1−1, k is number of exp’s bits
Sin ...
datalab-handout Lab
datalab-handout
温馨提示:内有解法剧透,未完成前请不要阅读。其中代码,仅供本人回忆用。
bitXor
要求我们使~和&这两个位运算符实现异或运算,最大操作次数不超过14次。
我们扩大条件,考虑~,&,|这三个位运算如何实现异或。比较容易想到(!a&b)∣(a&!b)(!a\&b)|(a\&!b)(!a&b)∣(a&!b)即可实现异或运算。(这里的!指的是~)。
a=0,b=0,(!0&0)∣(0&!0)=0∣0=0a=1,b=0,(!1&0)∣(1&!0)=0∣1=1a=1,b=1,(!1&1)∣(1&!1)=0∣0=0a = 0, b = 0, (!0\&0)|(0\&!0) = 0|0 = 0\\
a = 1, b = 0, (!1\&0)|(1\&!0) = 0|1 = 1\\
a = 1, b = 1, (!1\&1)|(1\&!1) = 0|0 = 0\\
a=0,b=0,(!0&0)∣(0&a ...
虚继承
虚基类与菱形继承
多重继承问题
1234567891011121314151617181920212223242526272829303132#include <iostream>class PoweredDevice{public: PoweredDevice() { std::cout << "PoweredDevice created" << "\n"; }};class Scanner: public PoweredDevice{public: Scanner() { std::cout << "Scanner created" << "\n"; }};class Printer: public PoweredDevice{public: Printer() { std: ...
智能指针
Smart Pointer
在C++11中通过引入智能指针的概念,使得C++程序员不需要手动释放内存
智能指针的种类
std::unique_ptr
std::shared_ptr
std::weak_ptr
概述
C++的指针包括两种
原始指针(raw pointer)
智能指针
智能指针是原始指针的封装,其优点是会自动分配内存,不用担心潜在的内存泄露。
unique_ptr
在任何给定的时刻,只能有一个指针管理内存
当指针超出作用域时,内存将自动释放
该类型指针不可Copy,只能Move
创建方式
通过已有裸指针创建
12345Cat *c_p2 = new Cat("p2");std::unique_ptr<Cat> u_c_p2{c_p2};// 建议销毁原始指针c_p2 = nullptr;u_c_p2->cat_info();
通过new来创建
1234std::unique_ptr<Cat> u_c_p3{new Cat("dd")};u_c_p3-> ...
手写线程池
手写线程池
线程池原理
当我们使用线程的时候就去创建一个线程,这样的实现虽然很简便,但是在并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束的时候,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。
线程池的作用就是复用线程,当一个线程执行完任务后,并不被销毁,而是可以继续执行其他任务。
线程池的组成:
任务队列,存储需要处理的任务,由工作的线程来处理这些任务。
通过线程池提供的API函数,将一个待处理的任务添加到任务队列,或者从任务队列中删除。
已处理的任务会被从任务队列中删除。
线程池的使用者,调用线程池函数往任务队列中添加任务的线程(生产者线程)。
工作的线程(任务队列任务的消费者),N个
线程池中维护了一定数量的工作线程,他们不停的读任务队列,从里边取出任务并处理。
工作的线程相当于是任务队列的消费者角色。
如果任务队列为空,工作的线程会被阻塞
如果阻塞后有了新的任务,由生产者将阻塞解除。
管理者线程,1个
它的任务是周期性的对任务队列中的任务数量以及处于忙状态的工作线程个数进行检测
当任务过多的时候,可以适当创建一些新 ...
线程同步
线程同步
同步方式
对于多个线程访问共享资源(临界资源)出现数据混乱的问题,需要进行线程同步。常见的线程同步方式有四种:互斥锁、读写锁、条件变量、信号量。
互斥锁
通过互斥锁可以锁定一个代码块,被锁定的代码块,所有线程只能顺序执行(不能并行)。这样多线程访问共享资源数据混乱的问题就得到解决,需要付出的代价是执行效率降低,因为从并行处理退化到了串行处理。
1234567pthread_mutex_t mutex; //保存了锁的状态信息与线程ID// 初始化互斥锁// restrict 只有这个关键字修饰的指针可以访问指向的内存地址,其他指针不行。int pthread_mutex_init(pthread_mutex_t *restrict mutex, pthread_mutex_t *restrict attr);// 释放互斥锁资源int pthread_mutex_destroy(pthread_mutex_t *mutex);
参数:
mutex:互斥锁变量的地址
attr:互斥锁的属性,一般使用默认即可,指定为NULL
1int pthread_mutex_loc ...
群晖虚拟机安装
群晖虚拟机安装
虚拟机安装
首先在群晖套件中心下载Virtual Machine Manager
然后下载你需要安装的系统镜像。博主这里需要学习linux的一些常见知识,所以打算安装Centos7和ubuntu20这两个系统。
Centos7:centos-7.9.2009-isos-x86_64安装包下载_开源镜像站-阿里云 (aliyun.com)
Ubuntu20.04:ubuntu-releases-20.04安装包下载_开源镜像站-阿里云 (aliyun.com)
下载完镜像后,上传到群晖中。
打开Virtual Machine Manager,然后点击新增。
经过一系列配置后,将启动ISO文件选择为我们上传的系统镜像即可。
最后启动虚拟机,进行centos系统的安装与配置即可。
ssh连接
在同一个局域网内,我们使用另外一台电脑对群晖系统上的虚拟机进行连接。
首先,我们需要在虚拟机内安装ssh(如果没有)。
1sudo apt install openssh-server
然后我们开启默认端口号
1vi /etc/ssh/sshd_config
将我框出的语句的#删掉 ...
多线程(一)
线程简介
线程是轻量级的进程。操作系统会以进程为单位,分配系统资源。进程是资源分配的最小单位,线程是操作系统调度执行的最小单位。
线程与进程
进程有独立的地址空间,多个线程共用同一个地址空间。
线程更加节省系统资源。
在一个地址空间中,每个线程都有属于自己的栈区,寄存器。
在一个地址空间中,代码段,堆区,全局数据区,文件描述符表都是线程共享的。
线程是程序的最小执行单位,进程是操作系统中最小的资源分配单位。
线程的上下文切换比进程快的多。
线程更加廉价,启动速度更快,退出也快,对系统资源的冲击小。
在处理多任务程序的时候使用多线程比使用多进程要更有优势,但是线程并不是越多越好。
处理复杂的算法(主要是CPU进行运算),线程的个数=CPU的核心数。
处理IO密集型任务时,因为可以分时复用CPU时间片,所以线程个数可以略大于CPU的核心数(两倍)。
创建线程
线程函数
每个线程都有一个唯一的线程ID,类型为pthread_t,是一个无符号长整形。
1pthread_t pthread_self(void); // 返回当前线程的线程ID
在一个进程中调用线程创建函数,就得到一个子线 ...
Linux基础入门(一)
Linux基础入门(一)
Linux内核
Linux系统分为内核空间和用户空间。内核空间是Linux操作系统的主要部分,但是仅有内核的操作系统是不能完成用户任务的。丰富并且功能强大的应用程序包是一个操作系统成功的必要件。
Linux的内核主要由5个子系统组成:进程调度,内存管理,虚拟文件系统,网络接口,进程间通信。
进程调度 SCHED
SCHED_OTHER:分时调度策略(默认),是用于针对普通进程的时间片轮转调度策略。
SCHED_FIFO:实时调度策略,是针对运行的实时性要求比较高,运行时间短的进程调度策略。
SCHED_RR:实时调度策略,是针对实时性要求比较高,运行时间比较长的进程调度策略。
内存管理 MMU
内存管理是多个进程间的内存共享策略。在Linux中,内存管理主要说的是虚拟内存。
虚拟内存可以让进程拥有比实际物理内存更大的内存,可以是实际内存的很多倍。
每个进程的虚拟内存有不同的地址空间,多个进程的虚拟内存不会冲突。
虚拟文件系统 VFS
在Linux下支持多种文件系统,如ext,ext2,minix,umsdos,msdos,vfat,ntfs等。
目前 ...