首先我们来学习PID这个概念,PID全称Process ID,是标识和区分进程的ID,它是一个全局唯一的正整数。原来Hello World进程运行时也有一个PID,只是它运行结束后PID也释放了,我们可以通过print_pid.go程序显示当前进程的PID。示例程序程序print_pid.go的源码如下,通过Getpid()函数可以获得当前进程的PID。
根据维基百科的定义,进程(Process)是计算机中已运行程序的实体。用户下达运行程序的命令后,就会产生进程。进程需要一些资源才能完成工作,如CPU使用时间、存储器、文件以及I/O设备,且为依序逐一进行,也就是每个CPU核心任何时间内仅能运行一项进程。我们简单总结下,进程就是代码运行的实体。
Thanks Wawa LeungOtherwise the book would be released two years ago
本书为开源电子书
走进守护进程Gradle 守护进程(有时也称为构建守护进程) 的目的是改善 Gradle 的启动和执行时间。我们准备了几个守护进程非常有用的用例。对于一些工作流,用户会多次调用 Gradle,以执行少量的相对快速的任务。举个例子:当使用测试驱动开发时,单元测试会被执行多次。当开发一个 web 应用程序中,应用程序会被组装多次。
fork 系统调用函数作用:创建一个子进程形式:pid_tfork(void);pid_t vfork(void);说明:使用 vfork 创子进程时,不会进程父进程的上下文返回值:[返回值=-1]子进程创建失败[返回值=0]子进程创建成功[返回值>0]对父进程返回子进程 PID #include <stdio.h>#include <sys/stat.h>#include <unistd.h>int main() { pid_t id = fork();
始终不能明白进程的正确理解和定义。就说我自己的理解吧进程是 CPU 调度的基本单位,对于 unix like 来说,当我们登录取得 bash 时,系统会根据用户的uid 和 gid 分配给我们一个进程,在当前 bash 下,这个进程就是所有进程的父进程,当我们执行一些命令时,每个命令都由一个新的子进程来完成。
Docker 容器在启动的时候开启单个进程,比如,一个 ssh 或者 apache 的 daemon 服务。但我们经常需要在一个机器上开启多个服务,这可以有很多方法,最简单的就是把多个启动命令放到一个启动脚本里面,启动的时候直接启动这个脚本,另外就是安装进程管理工具。本小节将使用进程管理工具 supervisor 来管理容器中的多个进程。
以下是用Dockerfile设置sshd服务容器,您可以使用连接并检查其他容器的卷,或者可以快速访问测试容器。 # sshd # # VERSION 0.0.1 FROM ubuntu:12.04 MAINTAINER Thatcher R. Peskens "thatcher@dotcloud.
LinuxGoDockerRunGoByExample
理解Unix进程Unix编程艺术Unix环境高级编程Go Web编程Go并发编程实战
Sendfile是Linux实现的系统调用,可以通过避免文件在内核态和用户态的拷贝来优化文件传输的效率。其中大名鼎鼎的分布式消息队列服务Kafka就使用sendfile来优化效率,具体用法可参见其官方文档。优化策略在普通进程中,要从磁盘拷贝数据到网络,其实是需要通过系统调用,进程也会反复在用户态和内核态切换,频繁的数据传输在此有效率问题。
SIGKILL是常见的Linux信号,我们使用kill命令杀掉进程也就是像进程发送SIGKILL信号。和其他信号不同,SIGKILL和SIGSTOP是不可被Catch的,因此下面的代码是能编译通过但也是无效的,更多细节可以参考golang/go#9463.c := make(chan os.Signal, 1)signal.Notify(c, syscall.SIGKILL, syscall.
如果你想创建一个目录并授予777权限,你需要怎么做?查看Go的API文档我们可以这样写。源文件为mkdir.go。package mainimport ( "fmt" "os")func main() { err := os.MkdirAll("/tmp/gotest/", 0777) if err != nil { panic(err) } fmt.
对进程有了深入理解后,我们编写实际应用可能遇到这些坑,这里总结一下。
实现Flock前面提到进程的文件锁,实际上Run也用到了,可以试想下以下的场景。用户A执行run pt-summary,由于本地已经缓存了所以会直接运行本地的脚本。同时用户B执行run -u pt-summary,加上-u或者--update参数后Run会从远端下载并运行最新的脚本。如果不加文件锁的话,用户A的行为就不可预测了,而文件锁很好得解决了这个问题。具体使用方法如下,我们封装了以下的接口。
Linux Namespaces是资源隔离技术,在2.6.23合并到内核,而在3.12内核加入对用户空间的支持。Namespaces是容器技术的基础,因为有了命名空间的隔离,才能限制容器之间的进程通信,像虚拟内存对于物理内存那样,开发者无需针对容器修改已有的代码。使用Namespaces阅读以下教程前建议看看,https://blog.jtlebi.fr/2013/12/22/introduction-to-linux-namespaces-part-1-uts/。
对于共享内存是好是坏,我们不能妄下定论,不过学习一下总是好的。不同进程之间内存空间是独立的,也就是说进程不能访问也不会干扰其他进程的内存。如果两个进程希望通过共享内存的方式通信呢?可以通过mmap()系统调用实现。Go实例Go也实现了mmap()函数支持共享内存,不过也是通过cgo来调用C实现的系统调用函数。Cgo是什么?
Linux很重要的设计思想就是一切皆文件,网络是文件,键盘等外设也是文件,很神奇吧?于是所有资源都有了统一的接口,开发者可以像写文件那样通过网络传输数据,我们也可以通过/proc/的文件看到进程的资源使用情况。内核给每个访问的文件分配了文件描述符(File Descriptor),它本质是一个非负整数,在打开或新建文件时返回,以后读写文件都要通过这个文件描述符了。
我们可以认为守护进程就是后台服务进程,因为它会有一个很长的生命周期提供服务,关闭终端不会影响服务,也就是说可以忽略某些信号。实现守护进程首先要保证进程在后台运行,可以在启动程序后面加&,当然更原始的方法是进程自己fork然后结束父进程。if (pid=fork()) { exit(0); // Parent process}然后是与终端、进程组、会话(Session)分离。
关注时代Java