- 博客(19)
- 收藏
- 关注
原创 说说进程
进程表述 书上对进程的叙述有很多,程序的执行实例或者正在运行的程序等,这些都是关于进程的表述;而对于内核来说是当担系统资源分配的实体。 可以想一下,当我们为执行某个功能而写一个程序后,这个程序是怎么变成一个进程的呢? 当程序被加载到内存中,从第一条指令开始执行,仅仅有代码是不能完成指定功能的,在执行过程中它需要一系列的资源(比如CPU、内存等),而操作系统又是怎么保证程序按照顺序执行的呢?操...
2018-03-30 21:58:31 218
原创 fd与FILE的比较
Linux中一切皆文件,这句话我们都知道,可见文件的重要性,因此文件的管理在Linux中占据了很大比重,那么操作系统怎么管理文件的呢? 要管理一个东西,那么必须经历两个步骤——描述和组织。当我们打开一个文件时,系统就会生成一个叫做file的结构体,系统正是用这个file结构体来描述单个文件的;既然已经描述了那么就要组织起来了,系统就会用一个数据结构把所有的文件都组织在一起以方便管理,而我们的进程...
2018-03-30 11:16:51 1610
原创 排序算法之交换排序1——冒泡排序
冒泡排序算法是一种简单的排序算法,它是稳定的,其时间复杂度为O(N^2),空间复杂度为O(1),一般而言不会用到这种排序方法,但这是初学者必学的排序方法之一。 算法代码实现:template <typename T>void BubbleSort(T *array, const int size){ assert(NULL != array && ...
2018-03-29 10:13:26 259
原创 排序算法之选择排序2——堆排序
堆排序是一个不稳定的排序算法,其时间复杂度为O(nlgn),空间复杂度为O(1)。其基本思想是对数组建立一个初始堆,然后进行一系列的交换和调整,最后得到需要的有序序列。 堆排序的一种实现:template <typename T>void Adjust(T *array, int parent, int size) //调整函数{ assert(NULL !...
2018-03-29 09:16:37 157
原创 基本IO系统调用简单应用
本文介绍5个io相关的系统调用——open、close、read、write、lseek。这5个函数被称为不带缓冲区的函数,标准C的输入输出函数就是对read和write的封装,先来看这些函数的函数原型。#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int open(const char* pathname, int
2018-03-28 22:24:38 377
原创 排序算法之选择排序1——直接选择排序
直接选择排序算法是一种简单的排序算法,它的时间复杂度为O(N^2),空间复杂度为O(1),它的时间复杂度与初始状态无关,因此总是做一些“重复性”的动作,并且它是不稳定的。 直接选择排序算法的实现:template <typename T>void SelectSort(T *array, const int size){ assert(NULL != array ...
2018-03-26 20:04:22 296
原创 排序算法之插入排序3——希尔排序
希尔排序又被称为减小增量的插入排序法,其时间复杂度在O(N^1.25)到O(1.6N^1.25)之间,空间复杂度为O(1),是一种比较高效的排序算法,希尔排序是一种不稳定的算法。关于希尔排序的介绍在任何一本数据结构书里面都有阐述,这里仅给出希尔排序算法的实现:#pragma once#include "compare.hpp"template <typename T>vo...
2018-03-26 18:56:05 380
原创 排序算法之插入排序2——折半插入排序
我们都知道插入法是在要插入的元素前面都已序的情况下进行比较—插入,直接插入法每个元素都有可能会经历多次交换才能找到它本应该待的位置。比如第100个元素,假如它应该待的位置为2,如果用直接插入法的话,就要比较99次,搬移98次。然而它前面的99个元素是已序的,显然有优化的空间,面对已序的序列我们最先想到的就是二分算法,我们可以先用二分法找到这个元素应该待的位置,然后一次性的将这个位置后面的元素后移,...
2018-03-26 17:59:45 976
原创 进程间通信之信号量
信号量也是三种XSI IPC之一,不过与消息队列和共享内存不同的是作为临界资源的信号量是以另一种临界资源的计数器的面目出现的。其基本作用机制为,为某种临界资源设定一定数量的信号量,当某个进程占用一份临界资源时信号量就减少相应的数值,当信号量为0时没有得到临界资源的进程就暂时性的进入“休眠”状态,待占用资源的进程将资源还回去后信号量增加,其他进程被唤醒,就又可以使用临界资源,这样就实现了临界资源的同...
2018-03-25 12:13:13 292
原创 进程间通信之共享内存
我们知道进程间同行的实质是让两个进程看到同一份资源。共享内存正是让两个进程看到同一份资源的方法之一。那么两个进程怎么共享一个内存呢? 我们都知道,每个进程都有自己的进程空间,进程的虚拟地址空间通过页表映射到物理内存上,而不同的进程的虚拟地址空间是相互独立的,也就不可能出现两个进程的虚拟地址空间橡胶的情况。但是,不同的进程虚拟地址空间都要映射到物理内存中,因此如果两个进程空间映射到同一块物理内存,...
2018-03-24 13:56:10 516 1
原创 进程间通信之消息队列
首先说一下什么是消息队列。消息队列是进程间通信的一种,它是由操作系统维护的以字节序列为基本单位的间接通信机制,它提供了一个进程向另一个进程发送一个带类型的数据块的方法。 我们知道用管道来实现进程间通信的机制是两个进程利用管道文件来实现数据交流,那么消息队列与管道有什么区别呢? 首先看一下管道通信机制的模型: 然后消息队列通信模型: 从上面图中可看出两者有着本质的区别。那么两个进程怎...
2018-03-21 23:42:19 2440 1
原创 排序算法之插入排序1—直接插入排序
插入是排序中常用的算法之一,也是每个编程人员必须掌握的排序算法之一。直接插入法的时间复杂度为O(n^2),空间复杂度为O(1),这是一种稳定的算法,其性能与待排序序列的初始状态有关。写这篇文章是为了实现插入排序中的直接插入排序算法。插入排序属于比较排序,因此,文首先定义一个比较器:template <typename T>struct Less{ bool operat...
2018-03-19 22:52:32 392
原创 进程间通信之管道
我们将一个进程到另一个进程的数据流称为管道,它是进程间通信最古老的方式。 管道分为两种:匿名管道与命名管道。 匿名管道 顾名思义,所谓的匿名管道自然就是没有名字的管道,这种管道通常用于有亲缘关系的进程间的通信。匿名管道通常由pipe函数来创建,当一个进程创建了一个匿名管道后,它们的模型就是这样的: 可以看出,仅连接了一个进程的管道于这个进程而言是无意义的,所以通常还会在创建管道后调用f...
2018-03-16 13:03:48 236
原创 派生类对象模型之单继承关系中的虚表剖析
我们都知道C++中利用虚函数实现动态多态,而这里多态的实现又于虚表(要与虚继承中的偏移量表区分开)有关,因此,在这里我探讨一下简单含虚函数的单继承关系中派生类对象模型与虚表问题。 首先给出如下继承关系:class Base{public: Base() : b(1) {} virtual void Print() { std...
2018-03-15 13:33:40 402
原创 派生类对象模型之虚继承派生类对象模型
虚继承的出现是为了解决菱形继承的二义性和数据冗余问题。什么是菱形继承的二义性和数据冗余问题呢?我们先给出一个菱形继承关系:class A{public: A() : a(0) { std::cout << "A()" << std::endl; } int a;};class Base1 : ...
2018-03-13 23:57:55 215
原创 派生类对象模型之菱形继承派生类对象模型
当继承关系超过两重后,就不可避免地出现菱形继承的问题,什么是菱形继承呢?我们来看一个图: 像这样,类B1、B2继承自类A,而类C又与类B1、B2是多继承的关系,整个继承关系呈菱形,这就是菱形继承。那么菱形继承存在什么问题呢?先给出这样一个继承关系:class A{public: A() : a(0) { std::cout <...
2018-03-13 20:34:50 369
原创 派生类对象模型之多继承派生类对象模型
C++是支持多继承的,那么多继承关系中派生类对象模型和单继承关系中有什么不一样呢?我们来看一看。 首先给出一个多继承关系:class Base1{public: Base1() : b1(1) { std::cout << "Base1()" << std::endl; } int b1;};...
2018-03-13 18:01:26 281
原创 派生类对象模型之单继承派生类对象模型
继承作为C++三大特性之一,无疑是非常重要的,而深入内存,弄懂派生类对象模型又是重中之重。本文我们来看看单继承中的派生类的对象模型。 首先我们建立一个简单的继承体系:class Base{public: Base() : b(1) { std::cout << "Base()" << std::endl; ...
2018-03-13 17:09:55 284
原创 左值与右值
什么是左值?什么是右值? 从字面上说所谓的左值就是能在赋值符号的左边出现的数值,右值就是可以在赋值符号右边出现的数值。 其实际意义也是如此,那么哪些值可以在赋值符号左边出现,哪些可以在等号赋值符号出现的呢? 这就要从分析赋值符号左边与右边出现的值的区别着手。能被赋值的数,一定在内存里面占用有一块内存空间,并且这块空间的内容可以改变,用以存储赋予的数值。而在赋值符号右边出现的数则无此要求,因为...
2018-03-11 23:49:49 1014
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人