Event Loop 是一个很重要的概念,指的是计算机系统的一种运行机制。 JavaScript语言就采用这种机制,来解决单线程运行带来的一些问题。 本文参考C. Aaron Cois的《Understanding The Node.js Event Loop》,解释什么是Event Loop,以及它与JavaScript语言的单线程模型有何关系。 想要理解Event Loop,就要从程序的运行模式讲起。运行以后的程序叫做"进程"(process),一般情况下,一个进程一次只能执行一个任务。 如果有很多任务需要执行,不外乎三种解决方法。 (1)排队。因为一个进程一次只能执行一个任务,只好等前面的任务执行完了,再执行后面的任务。 (2)新建进程。使用fork命令,为每个任务新建一个进程。 (3)新建线程。因为进程太耗费资源,所以如今的程序往往允许一个进程包含多个线程,由线程去完成任务。(进程和线程的详细解释,请看这里。) 以JavaScript语言为例,它是一种单线程语言,所有任务都在一个线程上完成,即采用上面的 继续阅读 >>


楚东方 17/07/28 00:12:16
何为堆 一个数组序列我们可以将其用完全二叉树或近似完全二叉树(不是满二叉树的完全二叉树)表示出来,当数组下标为i时,它的父节点为(i-1)/2,左孩子为(2i+1),右孩子为(2i+2),这种对应关系说明数组下标为0的地方也要存储数据。(关于完全二叉树和满二叉树我在这里不做介绍) 堆是在完全二叉树的基础上递归定义的,堆分为大顶堆和小顶堆。 大顶堆:根节点的数值大于孩子节点,完全二叉树的左右子树同时满足这个条件。 小顶堆:根节点的数值小于孩子节点,完全二叉树的左右子树同时满足这个条件。 从这种数据结构中我们可以发现:大顶堆的根节点也就是数组的第一个元素必定是最大值,而小顶堆必定是最小值,看到这,我想大家已经大概能感觉的到堆这种数据结构为什么可以用来排序了。 在来看个大顶堆和小顶堆的图解吧: 堆排序的过程 要想写出堆排序的代码,首先我们一定要清楚堆排序的过程,根据堆这种数据结构的特性,我总结了一下堆排序的过程: 首先我们需要将一个数组初始化为堆 在初始化堆的过程中我们必定要移动数组中元素的位置 初始化完 继续阅读 >>


董恒毅 17/07/27 20:25:04
下载地址 官网 使用方法 将下载的压缩包解压,咱么主要会用到以下文件 src ├── css │ ├── swipebox.css #css样式文件,二选一,推荐swipebox.min.css,文件更小 │ └── swipebox.min.css ├── img #这个目录的东需全部需要,放到你项目静态目录的根目录下 │ ├── icons.png │ ├── icons.svg │ └── loader.gif └── js #实现动态效果的js代码,二选一,推荐第二个 ├── jquery.swipebox.js └── jquery.swipebox.min.js 和 lib └── jquery-2.1.0.min.js # 重要,必须是这个版本的jq,最新版无效 开始你的代码 <!DOCTYPE html> <html lang="en"> <head> <!-- 脚本及样式文件(根据你文件的具体地址)--> <scri 继续阅读 >>


李余通 17/07/27 16:45:07
13、mutable和volatile        很少遇到这两个关键字,学嵌入式估计知道后者,深入研究C++的估计知道前者。        (1)mutable        在C++中,mutable是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中,甚至结构体变量或者类对象为const,其mutable成员也可以被修改。 [cpp] view plain copy  print? struct  ST      {        int a;      继续阅读 >>


楚东方 17/07/27 16:32:09
一、进程概述 1、程序,进程及线程间的区别与联系 程序是指一组指示计算机或其他具有消息处理能力装置每一步动作的指令,通常用某种程序设计语言编写,运行于某种目标体系结构上。 进程,是计算机中已运行程序的实体。进程为曾经是分时系统的基本运作单位。在面向进程设计的系统(如早期的UNIX,Linux 2.4及更早的版本)中,进程是程序的基本执行实体;在面向线程设计的系统(如当代多数操作系统、Linux 2.6及更新的版本)中,进程本身不是基本运行单位,而是线程的容器。 (进程是动态的,程序是静态的;进程是运行中的程序,程序是保存在硬盘上的可执行的代码。) 程序转化成进程 1、内核将程序读入内存,为程序分配内存空间 2、内核为该进程分配进程标识符(PID)和其他所需资源 3、内核为该进程保存PID及相应的状态信息,把进程放到运行队列中等待执行。 当程序转化为进程后就可以被操作系统的调度程序调度执行了。 线程,是操作系统能够进行运算调度的最小单位,线程在进程内部,线程与同属一个进程的其他线程共享进程拥有的全部资源。一个线程可以创建和撤销另一个线程,同一 继续阅读 >>


李猛 17/07/27 16:09:19
boost::bind是标准库函数std::bind1st和std::bind2nd的一种泛化形式。其可以支持函数对象、函数、函数指针、成员函数指针,并且绑定任意参数到某个指定值上或者将输入参数传入任意位置。 1. 通过functions和function pointers使用bind 给定如下函数: 1 int f(int a, int b) 2 { 3 return a + b; 4 } 5 6 int g(int a, int b, int c) 7 { 8 return a + b + c; 9 } 可以绑定所有参数,如: bind(f, 1, 2)等价于f(1, 2); bind(g, 1, 2, 3)等价于g(1, 2, 3); 也可以选择性地绑定参数,如: bind(f, _1, 5)(x)等价于f(x, 5),其中_1是一个占位符,表示用第一个参数来替换; bind(f, _2, _1)(x, y)等价于f(y, x); bind(g, _1, 9, _1)(x)等价于g(x, 继续阅读 >>


楚东方 17/07/27 16:07:41
进程控制 Linux进程 1.进程是一个动态的实体,是程序一次执行的过程。进程和程序的区别在于进程是动态的,程序是静态的,进程是运行中的程序,程序是一些保存在硬盘上的可执行代码。 线程是比进程更小的能独立运行的基本单位,线程是在进程内部。一个线程可以创建和撤销另一个线程,同一个进程中可以有多个线程并行执行。 2.Linux操作系统中,每个进程都是通过唯一的进程id标识的。而这个id是一个负数,每个进程除了id还有其他的标识信息,可以通过相应的函数获得。这些函数在unistd.h头文件中。 pid_t getpid(id) 获得进程id pdi_t getppid(id) 获得进程父进程的id pid_t getuid() 获得进程的实际用户id pid_t geteuid() 获得进程的有效用户id pid_t get 继续阅读 >>


陈苏扬 17/07/27 15:25:40
1. fork #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> int main (void) { pid_t pid; int i = 3; pid = fork(); switch(pid){ case 0: while(i--){ printf("A background process, PID:%d, ParentID:%d\n", getpid(), getppid()); } sleep(1); break; case -1: perror("Process creation failed.\n"); exit(1); 继续阅读 >>


王良 17/07/27 11:58:06
经历了上一周悲剧的学习,这一周,我决定让自己充实起来, 而进程控制(Peocess_Control)的学习尤为关键 所以,下面即为我的收获,本章的学习分为两部分 第一部分是进程的了解,以及相关操作 第二部分就是进程的一些其他操作,以及项目的一些实现要点 一,进程 进程的概念 了解什么是进程,进程的概念以及特点. 进程的概念总结后有以下几点:(进程与程序,线程的区别) 进程是一个动态的实体,是操作系统分配资源的基本单位 进程与程序的区别在于: 程序只是代码块,而进程是将代码移至内存中,之后为其分配资源以及空间运行中的程序, 可以这样理解进程,即特点之一是动态的 进程与线程: 为了使计算机能够在同一时间执行更多的任务,又在进程中划分了多个线程, 线程是操作系统所能操作控制的最 小单位, 进程分配有资源和内存,对于这些内容,线程不单独享用,多个线程共享这些资源以及内存, 同一个进程可以创建和撤销多个线程, 多个线程可以在进程中并行进行. 以上即为进程的基本概念. 其实我们可以从计算机的发展过程来看: 1.进程最早 继续阅读 >>


陈森 17/07/27 11:21:44
线程特定数据 线程特定数据,也称之为线程私有数据,是一种存储和查询某个特定线程相关数据的一种机制。使用线程特定数据的原因是:我们希望每个线程可以访问它单独的数据副本,而不需要担心与其他线程的同步访问问题。 而实际上由于每一个线程都可以平等地访问进程空间里的所有内容,我们并不能完全地屏蔽掉这种访问,但我们可以设计使得很难在编码无恶意的情况下访问到不应当访问的数据。 在使用线程特定数据之前,我们需要一个键,这个键将用于对线程特定数据的访问和修改。 键 创建键 int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); 返回值:若函数执行成功则返回0,反之则返回错误码。 key:创建的新键将保存在参数所指的内存区域中。 destructor:当线程退出时,若数据地址已经被设置为非空值,则会调用这个函数指针指向的函数完成收尾工作,给予他的参数是这个数据的地址。 取消键 int pthread_key_delete(pthread_key_t key) 继续阅读 >>


娄泽豪 17/07/27 11:04:30