程序计数器:记录当前执行指令的下一行指令地址。
程序:存储在磁盘上的可执行文件。
进程:运行中的程序/进程是一组有序指令+数据+资源的集合。
操作系统通过PCB(进程控制块/进程描述符)记录进程的相关属性(pid、ppid、优先级、程序计数器、程序上下文等),它不能记录过程,只能记录过程的型关信息。
进程控制块就是一个结构体,通过双向循环链表管理(基本的数据结构)
进程新生成时,必须先分配PCB结构,后才生成进程主体。进程结束时,先释放主体,当满足一定条件时才会释放PCB结构。
运行:CPU正在执行进程中的指令。
就绪:等待CPU执行的过程。
阻塞:等待I/O事件的发生等。
运行——阻塞:缺某些资源
阻塞——就绪:资源满足,等待再次调度
就绪——运行:时间片用完
fork:复制进程
#include
#include
#include
#include
#include
#include
#include
#include
int main()
{
//fork()||fork();
fork()&&fork();
printf("A\n");
exit(0);
}
子进程从fork()之后开始执行
int main()
{
int i=0;
for(;i<2;i++)
{
fork();
//printf("A\n");//6个A
printf("A");//输出缓冲区 8个A
}//把缓冲区中的A也复制到子进程中
exit(0);
}
//缓冲区刷新的条件
1、缓冲区满
2、虽然没有满,但是强制刷新(fflush(stdout)或者"\n")
3、程序退出,会先刷新缓冲区
int main()
{
char *s=NULL;
int n=0;
pid_t pid = fork();
assert(pid!=-1);
if(pid==0)
{
s="child";
n=3;
}
else
{
s="parent";
n=7;//子进程先于父进程结束,成为一个僵死进程
//父进程没有调用wait()函数获取子进程的退出码,此时子进程变成僵死进程,父进程结束后init收养子进程,init会自动调用wait()函数获取子进程的退出码,将子进程结束
}
int i=0;
for(;i
int main()
{
char *s=NULL;
int n=0;
pid_t pid = fork();
assert(pid!=-1);
if(pid==0)
{
s="child";
n=7;
}
else
{
s="parent";
n=3;//父进程先于子进程结束
//init收养子进程,子进程结束后,init会自动调用wait()函数获取子进程的退出码,将子进程结束。init进程id为1
}
int i=0;
for(;i
//a.c文件 abcdef
//文件偏移量自动后移
int main()
{
int fd=open("a.c",O_RDONLY);
assert(fd!=-1);
pid_t pid=fork();//父进程打开的文件,fork后,在子进程中也可以访问(共享)fork复制了进程描述符pcb(pcb里包括文件表,文件偏移量)
assert(pid != -1);
if(pid == 0)
{
char buff[32]={0};
read(fd,buff,1);
printf("child:buff=%s\n",buff);
sleep(1);
read(fd,buff,1);
printf("child:buff=%s\n",buff);
}
else
{
char buff[32]={0};
read(fd,buff,1);
printf("parent:buff=%s\n",buff);
sleep(1);
read(fd,buff,1);
printf("parent:buff=%s\n",buff);
}
close(fd);
exit(0);
}
//文件偏移量自动后移
int main()
{//先fork后open,此时文件还没有打开,分别有自己的文件偏移
pid_t pid=fork();//fork复制了进程描述符pcb(pcb里包括文件表,文件偏移量)
assert(pid != -1);
int fd = open("a.c",O_RDONLY);
assert(fd!=-1);
if(pid == 0)
{
char buff[32]={0};
read(fd,buff,1);
printf("child:buff=%s\n",buff);
sleep(1);
read(fd,buff,1);
printf("child:buff=%s\n",buff);
}
else
{
char buff[32]={0};
read(fd,buff,1);
printf("parent:buff=%s\n",buff);
sleep(1);
read(fd,buff,1);
printf("parent:buff=%s\n",buff);
}
close(fd);
exit(0);
}
#include
#include
#include
#include
#include
#include
int main()
{
char* s=(char*)malloc(128);//只有父进程malloc
assert(s~=NULL);
pid_t pid=fork();//父进程malloc的空间也会给子进程准备同样的一份
assert(pid!=-1);
if(pid==0)
{
strcpy(s,"child");
}
else
{
strcpy(s,"parent");
}
printf("s=%s\n",s);
free(s);//同一块空间不能被free两次
exit(0);
}
int main()//如果程序没有结束,没有free会发生内存泄漏
{
char *s=(char*)malloc(1024*1024*1024);//申请1G空间,没有free 程序结束后释放
assert(s!=NULL);
memset(s,0,1024*1024*1024);
exit(0);
}
/*int main()//程序运行完没有产生内存泄漏
{
char *s=(char *)malloc(128);
assert(s!=NULL);
memset(s,0,128)
exit(0);
}*/