程序:存储在磁盘上的二进制可执行文件。是静态的,一个程序可生成多个进程。
进程:一个正在运行的程序,是系统进行资源分配的基本单位。是动态的,是一次程序的实例化。
Linux进程描述符:struct task_struct
进程在其生命周期存在的状态:
就绪:所有资源准备完成,等待cpu空闲的状态
运行:在cpu上真正执行的状态
阻塞:等待某些事件发生,时间未发生前,不能被cpu调度的状态。
进程由进程控制块和实体组成:
就绪----》运行:系统进行进程调度
运行---》就绪:分配给进程的时间片用完
运行---》阻塞:需要某些事件发生才能运行(阻塞函数)
阻塞---》就绪:等待的事件已经发生,只能转到就绪态,不能直接转到运行态
除此之外,进程还有创建,退出,就绪/挂起,阻塞/挂起等状态
线程:进程内部的一条执行路··径,是系统进行调度的基本单位。
在linux中线程的实现:在Linux中线程的实现十分独特,从内核的角度来说,并没有线程的概念,Linux把所有的线程都当作进程来实现,内核并没有准备特别的调度算法或是定义特别的数据结构来表示线程。相反,线程仅仅被当做一个与其它进程共享某些资源的进程。每个线程都有唯一隶属于自己的task_struct,所以在内核中,它看起来就像一个普通的进程(只是该进程和其他一些进程共享某些资源,如地址空间)
僵死进程:子进程先于父进程结束,父进程没有获取子进程的退出码,此时,子进程变成僵死进程。
对僵死进程的处理方式:父进程调用wait获得退出码,或父进程先结束,让init进程接管子进程。
fork()复制过程:一个现有进程调用fork函数创建一个新的进程(复制进程 写时拷贝 以页为单位)
父进程打开的文件,会被复制到子进程中,父子进程共享打开的文件。
1)分配pid
2)分配进程描述符也就是PCB,同时分配好内核栈
3)复制进程实体,即:打开的文件,工作目录,信号信息,进程地址空间等等
4)用父进程内核栈上存放的现场信息,初始化为子进程的现场信息,并将eax置为0
5)将父进程的时间片分子进程一半,设置进程状态为就绪。
fork哪些被复制,哪些被共享?
参考博客:https://blog.csdn.net/qq_35191331/article/details/79803548
https://blog.csdn.net/xy010902100449/article/details/44851453
复制资源:打开的文件描述符,子进程获得父进程的数据空间,堆和栈的副本,注意是子进程拥有的副本,并不共享这些存储空间的部分。打开的文件 实际用户ID、实际组ID、有效用户ID、有效组ID 添加组ID
进程组ID 对话期ID 控制终端。 设置-用户-ID标志和设置-组-ID标志 当前工作目录
根目录 文件方式创建屏蔽字 信号屏蔽和排列 对任一打开文件描述符的在执行时关闭标志
环境 连接的共享存储段(共享内存) 资源限制
共享资源:代码段,数据段和用户堆栈内存空间并没有复制一份,而是与子进程共享。
父进程设置的文件锁,互斥锁等锁被共享
实际用户ID在某一时刻可具有的最大进程数:CHILD_MAX 整形能表示的范围内 32768
关于fork的一些笔试题:
0
分析:fork()||fork(),当第一个fork为1时,第二个fork不执行,此时第一个fork已经复制出一个fork,当第一个fork为0,第二个fork执行,第二个fork又复制出一个fork,所以最后结果打印出来为三个A.
分析:在此次程序中,当i=0时,fork进行一次复制打印出两个A,当i=1时,此时自己的fork进行复制,打印出两个A,再加上i=0时已经生成的两个fork再进行运行,又生成2个A,所以总共是6个A。
分析:跟个程序不同的是,此次生成的A并没有进行输出,而是存放再缓冲区中,所以多出的两个A应该是进行fork时里面生成的缓冲区的A。
分析:第一次执行printf生成一个A,存放在缓冲区中,没有进行输出,然后进行write执行,write进行程序的直接输出,fork后,print里面没有输出的A也进行fork,所以得到AA,程序输出为BAA。
关于函数write(1,"B",1);第一个1表示标准输出,B为字符串,后面1表示一个字节(长度)
write表示直接投到屏幕上(系统调用),而printf /n.fflush表示将数据没有直接打印出来,而是存放在缓冲区中。
文件描述符:open打开一个文件,会得到一个文件描述符open,read,write,close.
信号:signal:改变信号的响应方式。
kill:发送信号
默认:SIG_DFL
忽略:SIG_IGV
自定义:fun
SIGCHID:子进程状态发生,发给父进程
SIGINT:ctrl+c
kill pid:发送信号
kill -9 pid:发送9号,9号不允许改变响应方式。