地址空间(虚拟地址) 操作系统在管理内存时,每个进程都有一个独立的进程地址空间,进程地址空间的地址为虚拟地址,对于32位系统,虚拟地址为2^32=4GB 高位 1GB 为内核空间,地位的 3GB 为用户空间 虚拟地址包含以下部分 Kernal Space 文本段(.text) : 包含程序的可执行代码 已初始化数据段(.data) : 静态变量和全局变量 为初始化数据段(.bss) : 堆(.stack) : 局部变量 栈(.heap) : malloc 多进程 不管是同一台宿主机的不同进程还是不同宿主机的不同进程,都属于多进程 fork()出来的子进程与父进程唯一的区别在于创建的时间点不同,并且子进程的地址空间是fork()时对父进程地址空间的复制 由于进程没有共同的地址空间,不能通过操作同一个变量(地址)来通信,所以就没有“进程同步”一说了 进程通信 普通文件 :多个进程操作同一文件,需要文件锁 管道 : 半双工方式(数据可以在一个信号载体的两个方向上传输,但是不同同时传输) 共享内存 :同一物理内存被映射到多个进程的地址空间,那就存在进程共享同一内存区域,必然需要同步机制 socket pair : 全双工方式 socket 以上方式除了最后一种,其余的都只能用于同一宿主的不同进程,最后一种能用于同一宿主的不同进程和不同宿主的不同进程 据说是腾讯的面试题: void main(int argc, char *argv[]) { for(int i=0; i<2; ++i){ fork(); printf("g"); } } 问最后输出几个g?

read more


Docker环境搭建 由于Docker对windows支持不是特别好,所以选择在Linux上配置docker环境。 ### 下载 Docker[https://www.docker.com/] 使用‘lsb_release -a’命令查看系统版本,下载对应的docker版本 安装 $ sudo dpkg -i docker-version.deb 安装过程中可能会出现insserv相关的警告,这个警告不会影响docker的正常使用。 测试 官网推荐使用docker run hello-world来测试docker是否安装成功!但是执行这个命令时要从docker-hub上下载下来然后再运行的,所以在没有网络的情况下 是会失败的(因为笔者所在公司限制,访问外网比较麻烦)。如果没有网络可以选择下面的方法: 查找docker可执行程序 sudo find / -name dockerd 查看docker进程 ps -ef grep docker 如果没有找到进程,运行上步找到的可执行程序 Docker镜像制作 Tomcat Tomcat[http://tomcat.apache.org/] 下载时要选择正确的安装包! 有些包需要从新的编译后才能运行,所以选择已经编译好的包(编译好的包解压后包含了jar文件) Jenkins[https://jenkins.io/] JDK[http://www.oracle.com/technetwork/java/javase/downloads/index.html] Ubuntu镜像 https://hub.docker.com/explore/[https://hub.docker.com/explore/] https://partner-images.canonical.com/core/[https://partner-images.canonical.com/core/] 基础镜像制作 $ docker import ubuntu-version.tar.gz jenkins/ubuntu $ docker images JDK Tomcat等环境 Java cp /path/to/jdk-version.tar.gz . tar -zxvf jdk-version.tar.gz mv jdk-version jdk Tomcat cp /path/to/apache-tomcat-version.tar.gz . tar -zxvf apache-tomcat-version.tar.gz mv apache-tomcat-version tomcat Jenkins cp /path/to/jenkins-version.war /path/to/tomcat/webapps Dockfile编写 FROM jenkins/ubuntu MAINTAINER your-name your-email ENV DEBIAN_FRONTEND noninteractive ADD /path/to/jdk jdk ADD /path/to/tomcat tomcat ENV JAVA_HOME /jdk ENV JRE_HOME /jdk/jre ENV TOMCAT_HOME /tomcat...

read more


在使用matplotlib时,经常看到这样的现象:大部分的都用matplotlib.pyplot.figure来举例子。但都是单独使用matplotlib的情况! 然而,在应用的场景下,都需要把matplotlib嵌入到图像设备中,诸如PyQt,WxPython等,而在嵌入设备的场景下,都使用的是matplotlib.figure来举例的! 所以在初接触时就非常的困惑了,百度不到结果,Google的结果也是非常少的!所以到目前为止,笔者也还是有疑问的。 matplotlib.pyplot是面向过程的,而matplotlib.figure是OO(Object Oriented)。 matplotlib.pyplot.figure和matplotlib.figure.Figure类型不同,查看源码可知前者类型为figManager.canvas.figure,后者为Figure(继承于Artist) 在何种情况下,matplotlib可以嵌入到其他设备(已PyQt为例) 必须是QObject或其子类 在嵌入时都会from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas 在源码中可以看到这样的继承关系 FigureCanvasQTAgg->FigureCanvasQT->QtGui.QWidget,所以可以简单的认为FigureCanvasQTAgg是QWidget类型的! 所以出现这种混淆的情况主要是因为一个思维的转变!从面相过程到面相对象。

read more


hello world 最基本CMakeLists文件看起来像是这样: cmake_minimum_required(VERSION 3.0) project(Tutorial) add_executable(Tutorial tutorial.cxx) tutorial.cxx可以是最简单的hello world程序,如下: #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { printf("Hello world!\n"); return 0; } 添加版本号 cmake_minimum_required(VERSION 3.0) project(Tutorial) # version set (Tutorial_VERSION_MAJOR 1) set (Totorial_VERSION_MINOR 0) # configure file, pass the version number to source file configure_file ( ${PROJECT_SOURCE_DIR}/TutorialConfig.h.in ${PROJECT_BINARY_DIR}/TutorialConfig.h ) include_directories(${PROJECT_BINARY_DIR}) add_executable(Tutorial tutorial.cxx) TutorialConfig.h.in #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ tutorial.cxx #include <stdio.h> #include <stdlib.h> #include "TutorialConfig.h" int main(int argc, char *argv[]) { printf("Version:%d.%d\n", Tutorial_VERSION_MAJOR, Tutorial_VERSION_MANOR); printf("Hello world!\n"); return 0; } 引入自定义库 目录结构如下 ---example |---------hello_world.cxx |---------CMakeLists.txt |---------TutorialConfig.h.in |---------math |--------mymath.cxx |--------CMakeLists.txt 主CMakeLists.txt cmake_minimum_required(VERSION 3.0) project(Tutorial) # version set (Tutorial_VERSION_MAJOR...

read more


ev_epoll.c/ev_kqueue.c/ev_poll.c/ev_port.c/ev_select.c都是IO复用的封装,现在以epoll IO复用来讲解;** ev_epoll.c包含如下函数 void epoll_modify(EV_P_ int fd, int oev, int nev) void epoll_poll(EV_P_ ev_tstamp timeout) int inline_size epoll_init(EV_P_ int flags) void inline_size epoll_destroy(EV_P) void inline_size epoll_fork(EV_P) epoll_init int inline_size epoll_init (EV_P_ int flags) { #ifdef EPOLL_CLOEXEC backend_fd = epoll_create1 (EPOLL_CLOEXEC); if (backend_fd < 0 && (errno == EINVAL || errno == ENOSYS)) #endif backend_fd = epoll_create (256); if (backend_fd < 0) return 0; fcntl (backend_fd, F_SETFD, FD_CLOEXEC); backend_mintime = 1e-3; /* epoll does sometimes return early, this is just to avoid the worst */ backend_modify = epoll_modify; backend_poll = epoll_poll; epoll_eventmax = 64; /* initial number of events receivable per...

read more