printf函数并不会直接将数据输出到屏幕上,而是先放在缓存区中,只有以下三种情况满足,才会输出到屏幕。
1.1如果缓冲区满了,则直接输出
1.2 如果缓冲区没有满,则强制刷新缓存区
1.3 程序结束时
例如:
第一组代码:先打印 hello 再休眠2秒
第二组代码:先休眠2秒再答应hello
解释:其原因就是缓冲区,在第一个代码中,我们加有 n 进行对应的换行,强制对缓冲区进行了刷新;第2个程序没有对缓冲区进行刷新所以等待了2秒,遇到程序结束,那将对应的内容打印到屏幕上.
2·主函数 3个参数int main(int argc ,char *argv[],char* envp[]) //参数个数 参数内容 环境变量
3·复制进程Fork3.1 进程的定义:一个其中运行着多个线程的地址空间和这些线程所需要的系统资源
即“每一个运行着的程序就是一个进程”,用ps命令查看进程。
3.2 进程的管理:通过进程表来进行管理。进程表就类似一个数据结构-里面有进程的相关信息,包括进程的PID,进程的状态,命令字符串等。操作系统通过进程的PID对进程进行管理,PID为进程表的索引进程的表的长度是有限,所以一个操作系统,同时可以运行的程序是有限制的。
3.3 父进程:一般情况下,进程都是由另一个我们称之为父进程启动的,被父进程启动的叫子进程。父进程中fork返回值是子进程的pid,在子进程中返回的是fork返回值是0;在进程中打印的变量地址,都是逻辑地址(0,1,2,3......),不是物理地址;子进程会复制父进程的内存空间。
3·1 fork 方法pid_t fork();
函数的返回类型为pid_t 实际为整形(int),fork()函数会生成一个进程,调用fork()函数的进程为父进程,新生成的进程为子进程。在父进程中返回子进程的pid -(进程编号),在子进程中返回0,失败返回-1.
注意:
-
子进程执行 fork()后的所有内容,
-
先fork()再返回对应的值
-
子进程拷贝父进程的所有内容–在这有一个写实拷贝(要修改的拷贝,不修改的进行可以共享,可以提高运行效率)
-
子进程和父进程是 并发 执行(二者交替执行)
4.1 进程的主要3种状态:就绪;运行;阻塞
4.2 定义:子进程先于父进程结束,父进程没有获取子进程的退出码,如果父进程没有通过wait ,就会出现僵尸进程。因为虽然子进程虽然已经不在运行,但它仍然存在于系统中,因此退出码需要保存卡里,以备父进程今后的wait 调用使用,这时它就是一个僵尸进程。
4.3 如何处理僵死进程:父进程通过wait()完成。
4.3 Init进程收养孤儿进程
#include# include # include # include # include # include int main() { int n=0; char *s =NULL; pid_t pid=fork(); if(pid==-1) { exit(1); } if(pid==0) { s="child"; n=10; } else { s="parent"; n=3; //获取子进程的结束值-如果子进程已经执行结束,那么结束其子进程 // int val=0; // int id=wait(&val); // if(WIFEXITED(val)){ // printf("%d,val=%dn",id,WEXITSTATUS(val)); } for(int i=0;i 在上面代码中一部分被我注释掉的内容呢,就是通过 wait()来接受子进程的状态,如果子进程了,那么将其进程释放
5 内存地址问题在进程中打印的变量地址,都是逻辑地址(0,1,2,3......),不是物理地址;因为子进程在赋值的时候–是赋值了所有的父进程有关的内容,到新的一块儿内存上,所以物理地址是不相同的。操作系统在分内存的时候,分了很多块,不是说是给你一整块你就自己用吧,它也需要一个管家来管理和分配。所给的地址是一个逻辑地址,而逻辑地址是通过偏移量计算得来的。父进程打开文件,再复制子进程,那么父子进程共享打开的文件(偏移量共享0)
我们看到这张图,fork 一个子进程,而子进程的这个页表和父进程的大小都是一样的,我们看里面的编码顺序,序号也都是一样的,所以它打印的地址编号是一样的,不过他们在物理上并不属于同一块内存空间。
6 写时拷贝:写实拷贝并不复制整个进程的地址空间,而是让父进程和子进程共享一个拷贝。只有在需要写入的时候,数据才会被复制,从而使各个进程拥有各自的拷贝。资源的复制只有在写入的时候才进行,在此之前,只是以只读方式共享。 其目的是为了提高fork()的效率-修改时再复制。fork(),在复制父进制时,如果有修改页面时再进行复制,其它的时期进行共享,降低内存的占用率。
7 文件7.1.文件操作的系统调用:open,read,write,close
- 普通文件 归档–(Mp3,mp4,txt,都属于普通文件)
- 目录文件 d
- 管道文件 p,链接 l ,设备 c,b, 套接字 s
7.1.1创建一个可读可可写文件h.txt
7.1.2 权限标识
O_WRONLY 只写方式打开
O_RDONLY 只读方式打开
O_RDWR 读写方式打开
O_CREAT 文件不存在则创建
O_APPEND 文件末尾追加
O——TRUNC 清空文件,重新写入
mode:权限 如:0600 可读可写文件描述符—子进程可以访问父进程打开的文件 共享文件偏移量
返回值:文件描述符–参数介绍
ssize_t read(int fd,void *buf,size_t count);
fd 对应文件打开的描述符
buf 存放数据的空间
count 计划从文件中读取多少字节数据
返回值:实际读到的字节数int close(int fd) fd 为要关闭的文件描述符
0: 表示从键盘上读取数据 如:char buff[128]={0};read(0,buff,127)
1:表示将数据输出在屏幕上 如:write(1,"hello",5)->printf("hello")
frok小练习:



