1. 进程是unix系统中两个最重要的基础抽象之一(另一个是文件)

A process is a running program
A thread is the unit of activity inside of a process
 
the virtualization of memory is associated with the process, the threads all share the same memory address space
 

2. pid

The idle process has the pid 0
The first process that the kernel executes after booting the system, called the init process, has the pid 1
 
默认情况下,内核规定一个最大的进程ID值:32768(16位有符号数)
内核使用严格的线性方式为进程分配PID,如果当前所有分配的PID值最大为17,那么下一次分配的PID值为18
进程层级:每一个进程(init进程除外)都是从另一个进程引生的
Children normally belong to the same process groups as their parents
 

3. 运行新进程

In Unix, the act of loading into memory and executing a program image is separate from the act of creating a new process
exec system call:loads a binary program into memory, replacing the previous contents of the address space, and begins execution of  the new program
fork system call:create a new process
to execute a new program in a new process :first a fork to create a new process, and then an exec to load a new binary into that process
 
exec系列函数中,只有execve是系统调用,其余函数都是根据execve进行封装的C语言库函数
 
fork系统调用之后,子进程与父进程几乎完全相同,除了以下:
a.进程ID不同
b.挂起的信号被清除,并不被子进程继承
c.父进程的文件锁不被子进程继承
 
This “fork plus exec” combination is frequent and simple:

pid_t pid = fork();
if (pid == -) {
fprintf(stderr, "fork error\n");
} /* the child */
if (pid == ) {
const char* args[] = {"grep", NULL};
int ret = execv("bin/grep", args);
if (ret == -) {
fprintf(stderr, "execv error\n");
exit(EXIT_FAILURE);
}
}

4. copy-on-write

早期Unix中,实现fork非常简单,the kernel created copies of all internal data structures, duplicated the process's page table entries, and then performed a
page-by-page copy of the parent's address space into the child's new address space, 这样拷贝实现无疑是费时的
 
copy-on-write是一种减小资源复制开销的延迟策略。
如果多个用户请求对它所拥有的资源进行读操作,资源副本的拷贝是不需要进行的,每个用户只需要操作一个指向共同资源的指针即可。只要没有用户试图修改这个资源,那么副本的拷贝开销就可以避免。如果有一个用户确实需要修改这个资源,那么直到这个时候,资源才复制一份,复制的一份资源被交给需要修改的用户,其余所有用户继续共享原初的资源
 
在虚拟内存的具体示例中,copy-on-write是以内存页为单位进行的。
进程的内存页首先被标记为 read-only and copy-on-write, 如果有进程需要修改这个内存页,就产生页错误,就在这时,内核复制该内存页,并且内存页的copy-on-write标记被清除。
现代机器体系结构都硬件层面上支持copy-on-write
 

5. exit

当一个进程终止时,内核清除它包含的所有资源:分配的内存、打开的文件、信号量等
结束一个程序最经典的方式不是显式调用exit,而是 "falling off the end" of the program
 
当一个进程终止时,内核向其父进程发送 SIGCHLD 信号。默认情况下,该信号被忽略,父进程也可以调用 sigaction 捕捉该信号
 

6. wait

#include <sys/types.h>
#include <sys/wait.h> /* wait() returns the pid of a terminated child or −1 on error. */
pid_t wait (int *status); pid_t waitpid (pid_t pid, int *status, int options);
当pid==-1时,waitpid等待任一子进程,等同于 wait,即 wait (&status) 等同于 waitpid (−1, &status, 0)
 

7. system

#define _XOPEN_SOURCE    /* if we want WEXITSTATUS, etc. */
#include <stdlib.h>
int system (const char *command);
It is common to use system() to run a simple utility or shell script, often with the explicit goal of simply obtaining its return value
If command is NULL, system() returns a nonzero value if the shell /bin/sh is available, and 0 otherwise
 
here is a sample implementation for system():

/* my_system - sync spwans and waits for the command
* /bin/sh -c <cmd> .
*
* Return -1 on error of any sort, or the exit code from
* the launched process. Does not block or ignore any signals.
*/ int my_system(const char* cmd)
{
int status;
pid_t pid = fork();
if (pid == -) {
fprintf(stderr, "fork error\n");
return -;
} else if (pid == ) {
const char* argv[];
argv[] = "sh";
argv[] = "-c";
argv[] = "cmd";
argv[] = NULL;
execv("bin/sh", argv);
exit(-);
}
if (waitpid(pid, &status, ) == -) {
return -;
} else if (WIFEXITED(status)) {
return WEXITSTATUS(status);
}
return -;
}

8. 僵尸进程

a process that has terminated but has not yet been waited upon by its parent is called a “zombie.”
Zombie processes continue to consume system resources, although only a small percentage
如果一个父进程fork产生了子进程,那么该父进程就必须负责wait其子进程(回收僵尸子进程的所占资源)
如果一个父进程在终止之前没有wait其子进程呢? 内核会视察其所有子进程,并将这些子进程挂在init进程之下(确保任何进程在任何时候都有一个父进程),init进程会周期性wait其所有子进程,这些子进程最终还是会被回收资源,而不会长期以僵尸进程形式存在
 

9. Users and Groups

#include <sys/types.h>
#include <unistd.h> int setuid (uid_t uid);
int setgid (gid_t gid); uid_t getuid (void);
gid_t getgid (void);
Each process is a member of a process group,Process groups that contain more than one process are generally implementing job control
 
A command on the shell such as this one:
/*  one process group containing three processes */
$ cat ship-inventory.txt | grep booty | sort
 

10. 守护进程

A daemon is a process that runs in the background, not connecting to any controlling terminal
通常在系统启动时开始运行,并且以root权限运行,处理系统级任务,名字后缀一般为d
 
一个守护进程必须满足:a. 是init进程的子进程   b. 不允许与终端连接
 

Linux System Programming 学习笔记(五) 进程管理的更多相关文章

  1. Linux System Programming 学习笔记(九) 内存管理

    1. 进程地址空间 Linux中,进程并不是直接操作物理内存地址,而是每个进程关联一个虚拟地址空间 内存页是memory management unit (MMU) 可以管理的最小地址单元 机器的体系 ...

  2. Linux System Programming 学习笔记(八) 文件和目录管理

    1. 文件和元数据 每个文件都是通过inode引用,每个inode索引节点都具有文件系统中唯一的inode number 一个inode索引节点是存储在Linux文件系统的磁盘介质上的物理对象,也是L ...

  3. Linux System Programming 学习笔记(一) 介绍

    1. Linux系统编程的三大基石:系统调用.C语言库.C编译器 系统调用:内核向用户级程序提供服务的唯一接口.在i386中,用户级程序执行软件中断指令 INT n 之后切换至内核空间 用户程序通过寄 ...

  4. Linux System Programming 学习笔记(十) 信号

    1. 信号是软中断,提供处理异步事件的机制 异步事件可以是来源于系统外部(例如用户输入Ctrl-C)也可以来源于系统内(例如除0)   内核使用以下三种方法之一来处理信号: (1) 忽略该信号.SIG ...

  5. Linux System Programming 学习笔记(七) 线程

    1. Threading is the creation and management of multiple units of execution within a single process 二 ...

  6. Linux System Programming 学习笔记(六) 进程调度

    1. 进程调度 the process scheduler is the component of a kernel that selects which process to run next. 进 ...

  7. Linux System Programming 学习笔记(四) 高级I/O

    1. Scatter/Gather I/O a single system call  to  read or write data between single data stream and mu ...

  8. Linux System Programming 学习笔记(二) 文件I/O

    1.每个Linux进程都有一个最大打开文件数,默认情况下,最大值是1024 文件描述符不仅可以引用普通文件,也可以引用套接字socket,目录,管道(everything is a file) 默认情 ...

  9. Linux System Programming 学习笔记(十一) 时间

    1. 内核提供三种不同的方式来记录时间 Wall time (or real time):actual time and date in the real world Process time:the ...

随机推荐

  1. 爬虫遇到HTTP Error 403的问题

    # coding=gbk from bs4 import BeautifulSoup import requests import urllib x = 1 y = 1 def crawl(url): ...

  2. QT5:介绍

    一.简介 QT是一个跨平台的C++开发库,主要用来开发图形用户界面(Graphical User Interface,GUI) QT除了可以绘制漂亮的界面(包括控件/布局/交互),还可以多线程/访问数 ...

  3. 01_4_Struts路径问题

    01_4_Struts路径问题 1. Struts路径问题说明 struts2中的路径问题是根据action的路径而不是jsp路径来确定,所有尽量不要使用相对路径. 虽然可以使用redirect方式解 ...

  4. 使用max函数计算EXCEL个税公式

    1.Max()函数是求括号内的数的最大值.2.其中,第一和第二个大括号{}内的数,相信作为财务的应该很清楚,就是个人所得税的缴税比例,以及速算个人应缴所得税的相关数据.3.在EXCEL中,使用{}表示 ...

  5. 前端开发面试题之JavaScript(转自公众号)(1)

    js基本数据类型:Undefine Number Null Boolean String; js内置对象:数据封装类对象:object.Array.Boolean.String: 其他:Functio ...

  6. k8s的资源限制及资源请求

    容器的资源需求及限制:  需求:requests   ##定义容器运行时至少需要资源  限制:limits     ##定义容器运行时最多能分配的资源    requests:pod.spec.con ...

  7. 如何用纯 CSS 创作一个行驶中的火车 loader

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/RBLWzJ 可交互视频 ...

  8. 转载:将画布(canvas)图像保存成本地图片的方法

    之前我曾介绍过如何将HTML5画布(canvas)内容转变成图片形式,方法十分简单.但后来我发现只将canvas内容转变成图片输出还不够,如何能将转变后的图片保存到本地呢? 其实,这个方法也是非常简单 ...

  9. Python PyAudio 安装使用

    Python PyAudio安装: Python3.7 无法安装pyaudio pip install pyaudio提示error: Microsoft Visual C++ 14.0 is req ...

  10. selenium2等待元素加载

    1.硬性等待 Thread.sleep(8000); 所谓的硬性等待就是,执行完相应操作就等待我设置的8s.无论网速快与慢,网速快的话,也许5s就打开网页了,可是程序必须接着等待剩下的3秒. 网速慢的 ...