Process(进程)fork

程序计数器:记录当前执行指令的下一行指令地址。 

程序:存储在磁盘上的可执行文件。

进程:运行中的程序/进程是一组有序指令+数据+资源的集合。

操作系统通过PCB(进程控制块/进程描述符)记录进程的相关属性(pid、ppid、优先级、程序计数器、程序上下文等),它不能记录过程,只能记录过程的型关信息。

进程控制块就是一个结构体,通过双向循环链表管理(基本的数据结构)

进程新生成时,必须先分配PCB结构,后才生成进程主体。进程结束时,先释放主体,当满足一定条件时才会释放PCB结构。

运行:CPU正在执行进程中的指令。

就绪:等待CPU执行的过程。

阻塞:等待I/O事件的发生等。

运行——阻塞:缺某些资源

阻塞——就绪:资源满足,等待再次调度

就绪——运行:时间片用完

fork:复制进程

 

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<string.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/wait.h>


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<n;i++)
{
    printf("pid=%d,s=%s,&s=%x,ppid=%d\n",getpid(),s,&s,getppid());//&s同一个进程相同的逻辑地址翻译出的物理地址相同
    sleep(1);
}

exit(0);
}
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<n;i++)
{
    printf("pid=%d,s=%s,&s=%x,ppid=%d\n",getpid(),s,&s,getppid());//&s同一个进程相同的逻辑地址翻译出的物理地址相同
    sleep(1);
}

exit(0);
}
//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<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<string.h>
#include<sys/wait.h>

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);
}*/

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值