2017/04/27学习笔记

fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数执行另一个程序。当进程调用一个exec函数时,该进程的用户空间和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程ID不变.
将当前进程的.text .data替换为所要加载程序的.text .data,然后让进程从新的.text第一条指令开始执行,但进程ID不变,换核不换壳.

int execl();
int execlp();
int execle();
int execv();
int execvp();
int execve();

孤儿进程

父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为init进程,称为init进程领养孤儿进程。

僵尸进程

进程终止,父进程尚未回收,子进程残留资源存放于内核中,变成僵尸进程.
特别注意,,僵尸进程是不能用kill命令清除掉的。因为kill命令只是用来终止进程的,而僵尸进程已经终止。那用什么方法可清除掉僵尸进程?

wait函数

一个进程在终止时会关闭所有文件描述符,释放在用户空间分配的内存,但他的PCB还保留着,内核在其中保存了一些信息:如果是正常终止则保存退出状态,如果是异常终止则保留着导致该进程终止的信号是哪个。这个进程的父进程可以调用wait或waitpid获取这些信息,然后彻底清除掉这个进程。我们知道一个进程的退出状态可以在shell中用特殊保留$?查看,因为shell是它的父进程,当它终止时shell调用wait或waitpid得到它的退出状态同时彻底清除掉这个进程。

父进程调用wait函数可以回收子进程终止信息。该函数有三个功能:
1.阻塞等待子进程退出
2,。回收子进程残留资源
3.获取子进程结束状态。
pid_t wait(int * status)成功:清理掉的子进程ID:失败-1
当进程终止时,操作系统的隐式回收机制会:
1.关闭所有文件描述符
2.释放用户空间分配的内存。内核的PCB仍在。其中保存该进程的退出状态

waitpid函数

作用和wait相同,但可以指定pid进行清理,可以不阻塞

一次wait或waitpid函数调用只能回收一个子进程,清理多个子进程应使用循环

exec函数族

execlp --p =path 系统可执行程序
execl --list 用户自定义可执行程序

execv v 命令行参数 
execvp 
execve 环境变量
只有失败返回值,-1

IPC 进程间通信

Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷贝到内核缓冲区,进程2在从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信IPC.

在进程间完成数据传递需要借助操作系统提供特殊的方法,如:文件,管道、信号、共享内存、消息队列、套接字、命名管道等。随着计算机的发展,一些方法由于自身设计缺陷被淘汰或弃用。现今常用的进程间通信方式有
1.管道(使用最简单)
2.信号(开心最小)
3.共享映射区(无血缘关系)
4.本地套接字(最稳定)

管道

管道是一种最基本的IPC机制,作用于有血缘关系的进程之间,完成数据传递。调用pipe系统还是即可创建一个管道。有如下特质:
1.其本质是一个伪文件(实为内核缓冲区)
2.有两个文件描述符引用,一个表示读端,一个表示写端。
3.规定数据从管道的写端流入,从读端流出。
管道的原理:管道实为内核使用环形队列机制,借助内核缓冲区实现(4k);
管道的局限性:
1.数据自己读不能自己写。
2.数据一旦被读走,便不在管道中存在,不可反复读取。
3.由于管道采用半双工通信方式,因此,数据只能在一个方向上流动
4.只能在有公共祖先的进程间使用管道。

常见的方式有:单工通信 半双工通信 全双工通信

伪文件

共享存储映射

使用文件也可以晚上IPC,理论依据是,fork后,父子进程共享文件描述符。也就共享打开的文件。

存储映射IO
存储映射(memory-mapped IO) 使一个磁盘文件与存储空间的一个缓冲区相映射。于是当从缓冲区中取数据,就相当于读文件的相应字节。于此类似,将数据存入缓冲区,则相应的字节就自动写入文件。这样,就可以在不使用read和write函数的情况下,使用地址(指针)完成IO操作。
使用这种方法,首先应通知内核,将一个指定文件映射的储存区域中。这个映射工作可以通过mmap函数来实现

malloc大小可以为0
mmap 大小不可以为0

目录项

匿名映射

通过使用我们发现,使用映射区来完成文件读写操作十分方便,父子间通信也容易。
缺陷是每次创建映射区一定要依赖一个文件才能实现。通常为了建立映射区要open一个temp文件,创建好了再unlink,close 比较麻烦。可以直接使用匿名映射来代替。其实Linux系统给我们提供了创建匿名映射区的方法,无需依赖一个文件即可创建映射区。同样需要借助标志位参赛flags来指定

mkfifo

strace

时间: 2024-10-26 21:50:03

2017/04/27学习笔记的相关文章

2017/04/20学习笔记

man man 查看帮助文档echo $PATHreboot 重启poweroff 关机 vim --vimvim是从vi发展过来的一款文本编辑器vim的三种工作模式命令模式--打开vim之后,默认模式编辑模式--需要输液一些命令,切换到编辑模式末行模式--在末行模式下可以输入一些命令 :号 aiosAIOS w保存光标移动HJKL行首:0行尾:$文件开始:gg结束:G行跳转: 300G x:删除光标所在字符u: 撤销X:删除光标前字符dw:删除单词d0:删除光标前d$:删除光标后 Ddd:删除

2017/03/27学习笔记

程序的输入是指从输入文件讲数据传送给程序,程序的输出是指从程序将数据传送输出文件.C++输入输出包含以下三方面内容:对系统指定标准设备的输入和输出.即从键盘输入数据,输出到显示器.这种输入输出称为标准输入输出,简称标准IO.以外出磁盘文件为对象进行输入输出,即从磁盘文件输入数据,将数据输出到文件.以外存为对象的输入输出称为文件的输入输出,简称文件IO.度内存中指定的空间进行输入输出,通常指定一个字符串数组作为储存空间(实际上可以利用该空间储存任何信息).这种输入输出称为字符串输入输出,简称串IO

2017/04/29学习笔记

信号的概念 信号在我们的生活中随处可见,如:古代战争中摔杯为号:现在战争中的信号弹:体育比赛中使用的信号枪...他们都有共性: 1.简单 2.不能携带大量的信息 3.满足某个特设条件才发送.信号是信息的载体,Linux/Unix 环境下,古老 .经典的通信方式,现在依然是主要的通信手段.Unix早期版本就提供了信号机制,但不可靠,信号可能丢失.Berkeley和AT&T都对信号模型做了修改,增加了可靠信号机制.但彼此不兼容.POSIX.1对可靠信号例程进行了标准化. 信号的机制 A给B发生信号,

2017/04/05学习笔记

栈的应用 案例1:就近匹配几乎所有的编译器都具有检测括号是否匹配的能力如何实现编译器中的符号成对检测?#include <stdio.h> int main(){int a[4][4];int (*p)[4];p =a[0];return ;算法思路从第一个字符开始扫描当遇见普通字符时忽略当遇见左符号时压入栈中当遇见右符号时从栈中弹出栈顶符号,并进行匹配匹配成功:继续读入下一个字符匹配失败:立即停止,并报错结束:成功:所以字符扫描完毕,且栈为空失败:匹配失败或所有字符扫描完毕但栈非空当需要继承

2017/04/23学习笔记

#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <dirent.h> int getFileNum(char* root){ //open dir DIR* dir = NULL; dir = opendir(root); if(dir == NULL){ perror("opendir"); exit(1); } //遍历 struct dir

2017/04/22学习笔记

makefile中的函数 所以得makefile函数都是有返回值的 src=$(wildcard ./*.c) #从当前目录查找所有的.c文件obj=$(patsubst ./%.o, ./%.c, $(src)) #所有.c替换成点o .PHONY:clean 伪目标clean:rm $(obj) $(target) -f #删除.o和 目标 -f强制执行,不提示信息 clean:-rm $(obj) $target -f #命令前加 -,如果当前目录执行失败,忽略当前目录,继续向下执行 ma

2017.04 vue学习笔记---08表单控件绑定---基础用绑定value

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <style> div{ margin-bottom: 30px; } </style> <script src="js/vue.js"></script> <

2017.04 vue学习笔记---08表单控件绑定---基础用法

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <style> div{ margin-bottom: 30px; } </style> <script src="js/vue.js"></script> <

2017/05/05学习笔记

系统中所以的信息包括磁盘文件.内存中的程序.内存中存放的用户数据及网络上传送的数据都是由一串bit表示的.区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文.为了在C程序中做出好的编码选择,我们确实需要了解一些机器代码以及编译器将不同的C语句转化为机器代码的方式.比如一个switch是否总是比一个if-else语句高效的多?一个函数调用的开销有多大?while循环比for循环更有效么?指针引用比数组索引更有效么为什么将循环求和的结果放到一个本地变量中,会比其放到一个通过引用传递过来的参数