系统调用

Linux 将系内核的功能接口制作成系统调用,
Linux 有 200 多个系统调用, 系统调用是操作系统的最小功能单元。 一个操作系统,以及基于操作系统的应用,都不能实现超越系统调用的功能。
$ man 2 syscall # 查看所有的系统调用。

系统调用提供的功能非常基础 ,所以使用起来非常麻烦。

库函数

Linux 定义了一些库函数, 来将系统调用组合成某些常用的功能。
使用库函数对于机器来说没有效率上的优势, 但可以吧程序员从细节中解救出来。
实际上, 一个操作系统要称得上 UNIX 系统, 必须要拥有一些库函数, 如 ISO C 标准库,POSIX 标准等。

shell

shell 是一个特殊的程序,是一个命令解释程序。
shell 通过系统调用, 指挥内核工作 : shell 下通系统调用, 上通各种应用。

应用程序

应用程序使用如下的方式来与内核沟通 :
1. 直接调用系统函数
2. 调用库函数
3. 运行 shell 脚本。

Linux进程

进程是程序的具体实现,进程是执行程序的过程。 同一个程序可以执行多次,每次都可以在内存中开辟出独立的空间来装载, 从而产生多个进程。 不同的进程还可以拥有各自独立的IO接口。

操作系统的一个重要功能就是为进程提供方便, 比如 为进程分配内存空间,管理进程的相关信息等。

如何创建一个进程:

当计算器开机的时候,内核(kernal)只建立了一个 init 进程,Linux 内核并不提供直接建立新进程的系统调用。剩下的所有进程都是 init 进程通过 fork 机制建立的。

新的进程要通过老的进程复制自身得到, 这就是 fork。 fork 是一个系统调用, 进程存活于内存当中, 每个进程都在内存中分配有属于自己的一片空间。 当进程 fork 的时候,Linux 在内存中开辟出一片心的内存空间给新的进程, 并将老的进程中的内容复制到新的空间中,此后两个进程同时运行。老进程称为新进程的父进程, 新进程称为老进程的子进程。 一个进程除了有一个 PID 之外,还有一个 PPID,用来存储副进程的 PID,如果我们循着PPID 不断向上追溯,会发现其源头就是 init 进程。所以, 所有的进程也构成一个以 init 为根的树状结构。

fork 通常作为一个函数被调用。这个函数有两次返回,将子进程的PID 返回给父进程, 0 返回给子进程。实际上, 子进程可以查询自己的 PPID 知道自己的父进程是谁。

通常在调用 fork 函数之后,程序会设计一个 if 选择结构。 当 PID 等于 0时, 说明该程序为子进程, 那么让他执行某些指令, 比如使用 exec 库函数,读取另一个程序文件, 并在当前的进程空间执行(实际上我们使用 fork 的一大目的就是为某一个程序创建进程); 而当PID 为一个正整数时, 说明为父进程,则执行另外一些指令。由此, 就可以在子进程建立之后, 让他执行与父进程不同的功能。

子进程的终结:

当子进程终结时,他会通知父进程, 并清理自己所占据的内存, 并在内核里留下自己的退出信息(exit code, 如果为 0 ,则为正常退出;如果有错误或一场情况, 为 >0 的整数),在这个信息会解释该进程为什么退出。父进程在得知子进程终结时, 有责任对该子进程调用 wait 函数,wait函数可以从内核中取出子进程的退出信息,并清空该信息在内核中所占据的空间。 但是,如果父进程早于子进程终结,子进程就会成为一个孤儿进程, 孤儿进程会过继给 init 进程, init进程就成为该进程的父进程。 init 进程负责该子进程终结时,调用 wait 函数。

当出现 子进程的退出信息, 滞留内核中的状况(父进程不对子进程调用 wait函数), 这种情况下,子进程会成为僵尸进程。当大量僵尸进程堆积时, 内存空间会被挤占。

进程与线程;

在 UNIX 中, 进程与线程时有联系但不同的两个东西。
在 Linux 中,线程只是一种特殊的 进程, 多个线程之间可以共享内存空间和IO接口。 所以, 进程是 Linux 程序的唯一实现方式。

Linux 信号

进程间通信方式
① 管道 :
管道是由内核管理的一个缓冲区(buffer),管道的一端连接一个进程的输出。这个进程会向管道中放入信息。管道的另一端连接一个进程的输入,这个进程取出被放入管道的信息。一个缓冲区不需要很大,它被设计成为环形的数据结构,以便管道可以被循环利用。当管道中没有信息的话,从管道中读取的进程会等待,直到另一端的进程放入信息。当管道被放满信息的时候,尝试放入信息的进程会等待,直到另一端的进程取出信息。当两个进程都终结的时候,管道也自动消失。

② 信号
③ 共享内存
④ 消息队列

信号是一种向进程传递信息的方式,信号所能传输的信息比较粗糙,只是一个整数,但是,正是由于传递的信息量少,信号也便于管理和使用。信号常用于系统管理相关的任务。

信号是由内核管理的。
信号的产生方式:

1. 内核自己产生;
2. 其它进程产生,发送给内核,再由内核传递给目标进程。

信号的工作机制:

内核中针对每一个进程都有一个表存储相关信息,当内核需要将信号传递给某一个进程时, 就会在该进程相对应的表中的适当位置下入信号, 这样就**生成信号**;

当该进程执行系统调用时,在系统调用完成后退出内核时,会顺便查看信号内容, 如果有信号,则执行信号中的操作,此时叫做 **执行信号**;

从信号的生成到信号的传递的时间, 信号处于等待状态;

我们可以设计,让其生成的进程阻塞某些信号,也就是让这些信号处于等待的状态,直到进程取消阻塞或者无视信号。

常见信号
$ man 7 signal # 查阅更多信号

SIGINT : 终端该进程, interrupt
SIGQUIT : 退出该进程, quit
SIGTSOP : 暂停该进程,stop
SIGCONT : 通知暂停的进程,继续执行,
SIGALRM : 起定时器作用,通常是程序在一定的时间之后,才生成该信号。

在 shell 中使用信号

$ kill -SIG_NAME PID

信号处理(signal disposition)

一般情况下,进程对信号采取对应信号的默认操作, 但这并不绝队, 到那个进程决定执行信号的时候,有以下几种可能:
    1. 无视信号 ignore :信号被清除, 进程本身
    2. 默认操作 default : 每个信号对应一个默认的操作,
    3. 自定义操纵 catch : 执行进程中预设的对应于该信号的操作.

*进程会采取那种操作,取决于该进程的设计.*
*信号常常被用于系统管理,所以它的内容相当庞杂。深入了解信号,需要一定的Linux环境编程知识。*

Linux 进程关系

父进程与子进程

进程组, PGID

每个进程都会属于一个进程组(process group), 每个进程组可以包含多个进程. 进程组会有一个 进程组领导进程(process group leader), 领导进程的 PID 成为进程组的 ID, 即 PGID, 以识别进程组. 

    $ ps -o pid,pgid,ppid,comm

领导进程可以先终结, 此时进程依然存在, 并持有相同的 PGID, 知道进程组中最后一个进程终结.

将进程归为进程组的一个重要原因是, 可以将信号发送给一个进程组, 进程组中的所有进程都会收到该信号.

Linux 多线程与同步

Linux 进程间通信

Linux 文件系统的实现

Linux 进程,线程 -- (未完)的更多相关文章

  1. Linux进程线程学习笔记:运行新程序

    Linux进程线程学习笔记:运行新程序                                         周银辉 在上一篇中我们说到,当启动一个新进程以后,新进程会复制父进程的大部份上下 ...

  2. Linux 进程,线程,线程池

    在linux内核,线程与进程的区别很小,或者说内核并没有真正所谓单独的线程的概念,进程的创建函数是fork,而线程的创建是通过clone实现的. 而clone与fork都是调用do_fork(),差异 ...

  3. linux 进程线程

    linux下进程的最大线程数.进程最大数.进程打开的文件数   ===========最大线程数============== linux 系统中单个进程的最大线程数有其最大的限制 PTHREAD_TH ...

  4. linux学习笔记---未完待续,缓慢更新

    做为linux菜鸟,由于work的需要,慢慢的开始接触学习linux. <鸟哥的linux私房菜>学习笔记. 一.基础命令操作 1.显示日期的命令 date 执行date命令后,显示结果为 ...

  5. linux 进程线程拓展

    依次参考: 多线程和多进程的区别(小结) Linux内核源代码分析——fork()原理&多进程网络模型 Linux写时拷贝技术(copy-on-write) linux内核 do_fork 函 ...

  6. linux: cmake(未完,待更新)

    参考: http://blog.csdn.net/netnote/article/details/4051620 http://blog.csdn.net/fan_hai_ping/article/d ...

  7. Linux:cut命令...未完待续

    一.定义 正如其名,cut的工作就是"剪",具体的说就是在文件中负责剪切数据用的.cut是以每一行为一个处理对象的,这种机制和sed是一样的. 2.剪切依据 cut命令主要是接受三 ...

  8. inux进程/线程调度策略与 进程优先级

    目的: 系统性的认识linux的调度策略(SCHED_OTHER.SCHED_FIFO.SCHED_RR): 实时调度?分时调度? 混搭系统(实时任务+分时任务),怎样调度. linux的调度策略 l ...

  9. Linux进程与线程的区别

    进程与线程的区别,早已经成为了经典问题.自线程概念诞生起,关于这个问题的讨论就没有停止过.无论是初级程序员,还是资深专家,都应该考虑过这个问题,只是层次角度不同罢了.一般程序员而言,搞清楚二者的概念, ...

随机推荐

  1. java自带的http get/post请求servlet

    http请求方式太多,有java自带的,也有httpClient,用的地方还挺多,所以在此做一个小小的总结: public class HttpRequest { /** * 向指定URL发送GET方 ...

  2. __call()和__callStatic()实例详解

    <?php class Demo { //第一个参数是方法名,第二个参数是方法参数,以数组形式传入 public function __call($method,$args) { //遍历参数$ ...

  3. ListView控件详解

    ListView是个较为复杂的控件   1.定义 把它拽进来,系统会自动在Designer.cs里添加一个  this.listView1 = new System.Windows.Forms.Lis ...

  4. 如何使用.bas文件

    1. 确保你安装的是word 2010,打开word文档,,按ALT + F11打开VBE编辑器. 2.点击Normal,右键,在弹出的对话框中选择导入文件. 2. 选择需要使用的脚本的位置,然后点击 ...

  5. 初码-Azure系列-记一次从阿里云到Azure的迁移和部署

    有个客户在阿里云上,这次要迁移到Azure去,手工记一下流水账 原系统信息: 阿里云ECS单Web节点(8核16G,10000IOPS SSD云盘)+阿里云ECS单数据库节点(16核32G,15000 ...

  6. 用户输入与while循环

    函数input()的工作原理: 函数input()让程序短暂运行,等待用户输入一些文本,获取用户输入后将其存储在一个变量中 测试input()功能-- #!/usr/bin/env python#fi ...

  7. SmartCoder每日站立会议10

    站立会议内容: 准备为上交第一阶段项目进行加班,将各个页面联系起来,静态地图变为动态转换,考虑地图全屏或者是小屏即消息展示方式 1.站立会议照片:      2.任务展板: 3.燃尽图:

  8. 刨根究底字符编码之八——Unicode编码方案概述

    Unicode编码方案概述   1. 前面讲过,随着计算机发展到世界各地,于是各个国家和地区各自为政,搞出了很多既兼容ASCII但又互相不兼容的各种编码方案.这样一来同一个二进制编码就有可能被解释成不 ...

  9. hdu_A Walk Through the Forest ——迪杰特斯拉+dfs

    A Walk Through the Forest Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/ ...

  10. Python教程(2.2)——数据类型与变量

    和C/C++.Java一样,Python也有数据类型和变量两个概念. 数据类型 Python中的几个基本数据类型为整数(integer/int).浮点数(float/float).布尔值(boolea ...