应用

三. 多进程间的通信模型

UNIX的文件系统 UNIX中的文件系统术语有两个意思。一是指组织管理外存数据的方法,比如ext4/NTFS这样的文件系统。二是指UNIX中的虚拟文件系统VFS框架。这二者是有一定嵌套关系的,但本文的文件系统术语重点指代后者。 UNIX文件系统的架构设计哲学是“一切皆文件”。就是把一切能类比为传统意义文件的对象,统统作为UNIX定义的文件对象处理。 多线程的通信模型(IPC) 同进程下不同线程可以共享进程的虚拟化资源,所以通过编程语言全局变量与同步机制即可通信。但上文提到了进程的资源是被操作系统逻辑隔离的,所以需要其他机制来进行进程间通信。下面讨论一些系统线程间通信的模型。 1)共享内存: 共享内存是系统将相同的一块物理内存映射进不同进程地址空间的机制。共享内存通常是由某个进程创建但多个进程都可访问。这样就能够结合之前提到的同步机制来实现进程间通信,因为之前提到的同步机制大多数是支持进程间同步的(只是在例如Python中编程时会比较麻烦)。并且共享内存是最快的一种IPC方式。… 阅读全文

二. 多线程间的同步模型

多线程的线程安全 线程安全是指多线程同时使用共享资源时,并行或并发的线程可能不可预料的篡改共享资源,如下面代码所示。 Python from threading import * globalVar = 0def thd(): global globalVar while 1: a = globalVar + 1 globalVar = a a = globalVar - 1 globalVar = a print (globalVar) for i in range(100): Thread(target=thd).start() 1234567891011121314 from threading import *globalVar = 0 def thd():  global globalVar  while 1:    a… 阅读全文

一. 进程与线程的模型

并行与并发如图所示,假定一个计算机只能同时处理一个任务,有三个任务要解决。然后借此来了解并行与并发这两种方式。 1)并行:把任务同时分配给三台计算机,那同一时刻三个任务都是在执行中的。 2)并发:把任务分配给一台计算机,轮流完成一个任务的一个片段,同一时刻只有一个任务在执行中。 实际中的并行与并发往往混合在一起,比如可以把6个任务拆分为片段分配到3个计算机,如果画成类似上图的时间流程图,可以发现相对纯并发的时间流程图,该场景的任务片段在时间上会有1/2的重合部分。 另外需要注意一点,在并行与并发的概念中,往往会默认任务内部是无法知道任务被做了切片操作的,而且切片操作发生的时机也是无法预知的。所以在大多数情况下,并行与并发应该被理解为“并行与并发都是指任务在逻辑上是同时执行的”,而不去区分任务具体是并行还是并发,一般会统一称其为并发。并行并发是下文中线程的核心逻辑,但并行并发是一种更上层的高级概念,其可被用于分布式系统等更一般化的流程设计。… 阅读全文

HTTPS

引文:两种不同的加密场景   1)防篡改:例如HTTP常使用JWT这样一种Token,其原理是服务器端用公开的哈希函数+自定义字符串KEY构成新哈希函数(实际上与md5+salt密码的加密方案大致是等价的)。当用户登录时,服务端会产生一个JSONObject其中记录了登陆成功的用户名,登录状态失效时间等。然后在这个JSONObject后面附加用这个新哈希函数生成的哈希发给用户,用户之后在报头携带这个JWT使得服务器在每次请求应答中可以知道用户是否登录。由于KEY的保密性与哈希的不可逆特性,几乎不可能从JSONObject与哈希反推出哈希函数,所以当恶意用户企图篡改JSONObject时,无法算出新的哈希。这样一来当服务器颁发出Token后再收到Token时,一定知道其是不是自己颁发的。… 阅读全文

Python下的Linux异步非阻塞IO

Linux根文件系统 Unix中有“一切皆文件”的抽象设计。例如串口、socket、tty终端、内存等资源都对应了文件(fs),用户可读写这些文件,能方便的用统一的“文件操作”来操作资源与其IO,这就是根文件系统rootFS(类似RESTful) 内存文件:Linux中有些目录是“内存文件系统”,其把内存中的数据以“目录/文件”的形式整理出来,并且挂载到文件系统上,对其读写意味着某些特定的操作。如/proc(进程文件系统)是内核中进程相关数据整理成的文件系统、/dev/mem是全物理内存的景象、/dev/shm是临时文件系统(tmpfs)可把文件直接放进内存 tty文件:即字符设备文件(通常在/dev/ttyXXX),是不同的串口/USB设备、运行时终端的对应文件。其历史上是串口打字机的设备文件,等到出现了微型计算机/键盘/GUI后,终端替换了打字机的等价位置,但是Linux仍保留了“打字机”文件(可简单理解为终端命令被翻译成打字机的串行输入,试试cat/echo它们)… 阅读全文

Flask框架

RESTful架构设计 面向资源与使用URI表示资源的设计,这里资源与“状态”对立,所以是“无状态化”的设计。生产中常常希望后端程序是RESTful的,这可以充分的解耦前后端,实现前后端分离的开发与部署,并且由于服务端不记忆“状态”,而资源往往又是持久化的外部数据,所以RESTful天生支持分布式。 资源:用HTTP地址URI对应资源名词,并且利用好URI的树结构(比如 user/Jon/age) 动作:用HTTP方法作为对URI的操作动词(比如 DELETE user/6) 实现:JSON作为响应请求主体,kv型附加数据放入报头,响应状态用HTTP状态码描述,资源应设计的尽量“接近”数据库。业务实现有例如OAuth2认证,resource-based权限,多版本API上线等。   MVC框架 按抽象模块分层的设计,但通常是指实现了MVC设计的框架。其按模型Model、视图View、控制器Controller这三大模块拆分,其著名实现有SpringMVC等,是产业中最流行的框架。另外还有衍生的设计如MVVM、MTV等。… 阅读全文

生态与开发环境

C语言的特征与应用场景 C语言是种古老的语言,其相对于现在流行的语言来说,有几个特征: 1) 对于同样的程序逻辑,其C语言实现的性能是非常高的,通常仅次于汇编语言(ASM); 2) C语言通常会被直接编译成目标机器与操作系统下的程序,中间没有解释器和虚拟机; 3) C语言没有内置面向对象(OOP)语法,但其提供了跟Class有点像的结构体类型。如果真的想要在C语言下进行OOP,往往需要间接的通过一些其他的软件设计方法; 4) C语言离机器与操作系统更近,比方说C语言直接对程序员提供了内存模型; 5)  具有一定的跨机器与跨系统移植的能力,但仅限于源码级。比如相比Java的“1份代码,1次编译,n处运行”,C最多只能“1份代码,n处编译,n处运行”; 6) 开发效率较低,同样的逻辑C语言的代码量可能是Java的几倍,是Python的几十倍;… 阅读全文

HELLOWORLD程序

HelloWorld程序 给出C语言下的Hello,World程序hello.c。这个程序也会作为计算机系统中的分析案例。 C #include <stdio.h> int main(void) { printf("hello,world\n"); return 0; } 12345 #include <stdio.h>int main(void) {  printf("hello,world\n");  return 0;} 通过GCC编译器的命令“gcc ./hello.c”就可将代码编译为当前操作系统下的可执行文件“a.out”。然后通过命令“./a.out”就可执行它,其结果是在终端打印“hello,world!”。代码中的main函数是一种ANSI C标准给出的约定,其约定C程序执行入口是名叫main的函数,并且其返回值类型是int。main可以接受参数也可以不接受参数,接受参数的一种用法是接受执行时Shell传入的参数。… 阅读全文

变量、常量、作用域

变量 C语言是一种静态类型的语言,其在初始化变量时需要指定变量的类型,但其在语法层面不要求在变量初始化时必须赋值。比方说“int a”和“int a = 1”都是合法的变量初始化语法,在初始化后可以为变量再次的赋值。C语言中的变量分为如下几种: 1) 全局变量:不在花括号内的变量; 2) 局部变量:花括号内的变量; 3) 形式参数:函数传入的参数;   作用域 C语言的作用域靠花括号区分   C语言初始化新的变量是使用“int a = 1”这样的语法,这样的语句前还可以加入const关键字,这可以把a声明为常量,即执行完“const int a = 1”后a的值将不允许被改变。C语言中还有另一种“实现常量”的方式,就是利用预处理指令#define。比如“#define A 1”可以实现在程序中加入等于1的常量A。这两种方式的区别是const是程序的一部分,而#define不能算是程序的一部分,其会在非正式编译的预处理阶段把代码中的A换成1,然后再进行后续的正式编译。

基本数据类型

基本数据类型 — 空类型 C语言中的void关键字用于描述“没有具体类型或是没有内容”,其有3种常见使用场景: 1) 用于定义函数时说明其无返回值 (比如void f(int x,int y)的语法); 2) 用于定义函数时说明其没有参数(比如int f(void)的语法); 3) 用于定义无类型指针,可以指向任何类型的数据(void *p的语法);   基本数据类型 — int类型 整数(integer/int)类型由int关键字与long/short/unsigned组合而成。下面举例说明: 1) int:C90规定int取值范围至少为-32768~32767。这里的“至少”令人费解,因为在制定标准时考虑了对未来存储的兼容,在不同的机器/操作系统/编译器上,int可能允许更大范围的整数,比如在64位机器上,int会比16位机器的范围大;… 阅读全文
滚动至顶部