父子进程共享文件资源原理

进程打开的文件资源

如何通过代码实现访问fork前打开的文件描述符

//文件描述符
int fd = open();
pid_t n = fork();
if (n == 0) 
{
	//能不能通过fd访问打开的文件
    int num = write (fd, "hello", 5);
    if (num == -1)
    {
        printf("write error");
    }
} else
{
    sleep(2);//让子进程执行两秒钟
    write(fd, "world", 5);
}
close(fd);

用户态到内核态的切换过程

  • 内核态拥有我们系统最高访问权限,用户态最低访问权限

  • 什么时候需要从用户态切换到内核态?

    • 调用系统调用函数
    • 触发中断
  • open read write fork 都是系统调用函数

    • 系统调用号,每一个系统调用函数都有对应的系统调用号
  • int fd = open()函数的实质;

    1. 将函数对应的系统调用号保存到eax寄存器中

    2. 触发0x80中断-》进入到中断处理程序

    3. 保存程序上下文,为我们将来系统调用函数返回后,恢复现场使用

    4. 传递系统调用函数的参数

    5. 真正进入到内核空间,将内核数据段的、局部数据段的存到寄存器上

    6. 通过sys_open函数返回fd信息

      在这里插入图片描述

  • call[_sys_call_table+eax*4]

    //函数调用表
    //函数指针数组
    _sys_call_table[]= {
        sys_write;
        sys_read;
        ...
    }
    
  • 返回值通过eax寄存器记录和赋值

孤儿进程

  • 父进程结束,子进程未结束,则子进程称之为孤儿进程,但是系统会将所有的孤儿进程托管到系统进程init下,由init统一管理所有的孤儿进程。

    int main () 
    {
    	int pif = fork()assert(-1 != pid);
    	
    	if (pid == 0)
    	{
    		int i = 0;
    		for(;i < 5; i++)
    		{
    			printf("my father is %d\n", getppid());
    			sleep(1);
    		}
    	}
    	else {
    		ptintf();
    	}
    }
    

僵死进程

  • 进程实体结束,被内核释放,但是进程PCB结构依旧保存

  • 子进程结束,父进程未结束,并且父进程没有获取子进程退出状态。

int main()
{
	pid_t n = fork();
	asset(-1 != n);
	if (n == 0)
	{
		printf("i am child, start \n");
		sleep(2);
		printf("i am child., i will end");
	} else {
        int pid = wait(NULL);
        printf("father pid = %d\n", pid);
		pirntf("i am father , stat\n");
		sleep(100);
		printf("i am father ,i will end");
	}
}
  • pid_t wait(int *reval) 获取子进程的退出状态

    • 返回值为-1,调用失败
    • 返回处理的子进程pid值
    • reval:记录子进程退出状态
  • 阻塞运行

    • 调用函数时,如果条件未发生,则函数不会立即返回,而是等待条件发生
  • 非阻塞运行

    • 调用函数时,无论条件是否发生,函数都会立即返回
  • 调用wait会使父子进程串行运行

    • 如何让父子进程并发执行,而且在子进程结束后及时处理僵死进程??
    • 父进程不知道子进程什么时候会结束,所以父进程在开始运行时就调用wait等待子进程结束
      • 解决方案:父进程在子进程结束后再调用wait,子进程结束之前父进程执行自己的代码
        • 父进程如何知道子进程什么时候结束
          • 子进程结束时,将这一事件通知给父进程,父进程接受到事件,再去调用wait。
  • 信号:信号是操作系统预先定义好的某些事件。信号可以被产生,也可以被接受,产生和接受信号的主体都是进程

    • 信号的定义:/usr/include/bits/signum.h
      在这里插入图片描述
  • 信号的响应方式

    1. 默认

    2. 忽略

    3. 自定义(捕获)

      在这里插入图片描述

    • 如何修改信号的相应方式
      typdef void(*sig_Handle)(int *);
      Sig_Handler signal(int sig_type, Sig_Handle hander);
      //									信号相应方式(函数地址)
    
    • 子进程结束默认想父进程发送:SINCHLD信号
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值