进程控制 fork/getpid/getppid

函数原型

pid_t fork(void);失败返回-1;成功返回:① 父进程返回子进程的 ID(非负) ②子进程返回 0
pid_t getpid(void);获取当前进程 ID
pid_t getppid(void);获取当前进程的父进程 ID

fork函数

创建一个子进程。
pid_t fork(void);失败返回-1;成功返回:① 父进程返回子进程的ID(非负)②子进程返回 0

pid_t类型表示进程ID,但为了表示-1,它是有符号整型。(0不是有效进程ID,init最小,为1)
注意返回值,不是fork函数能返回两个值,而是fork后,fork函数变为两个,父子需【各自】返回一个。

getpid函数

获取当前进程ID
pid_t getpid(void);

getppid函数

获取当前进程的父进程ID
pid_tgetppid(void);

案例一 打印父子进程id

# include<stdio.h>
# include<stdlib.h>
# include<unistd.h>
int main()
{
  pid_t pid ;
  pid = fork();
  if(pid<0)
  {
      perror("fork error");
      
  }
  else if(pid==0)
  {
      printf("I am child pid =%d my father pid=%d\n",getpid(),getppid());
  }
  else
  {
      printf("I am father pid =%d my father pid =%d\n",getpid(),getppid());
  }
  return 0;
}

案例二 顺序打印5个进程

练习:通过命令行参数指定创建进程的个数,每个进程休眠1S打印自己是第几个被创建的进程。如:第1个子进程休眠0秒打印:“我是第1个子进程”;第2个进程休眠1秒打印:“我是第2个子进程”;第3个进程休眠2秒打印:“我是第3个子进程”。

# include<stdio.h>
# include<stdlib.h>
# include<unistd.h>
int main()
{
  pid_t pid;
  int i;
  for(i=0;i<5;i++)
  {
      pid =fork();
      if(pid==0)
      {
       break;
      }
  }
  if(5==i)//父进程 等待for结束自己台跳出
  {
      sleep(5);
      printf("I am father\n");
  
  }
  else//子进程 提前break跳出 打印
  {
      sleep(i);
      printf("I am %d child \n",i+1);
  }

  return 0;
}

父子进程间遵循读时共享写时复制的原则

相同部分:全局变量、.data、.text、栈、堆、环境变量、用户 ID、宿主目录、进程工
作目录、信号处理方式…

不同部分:1.进程 ID 2.fork 返回值 3.父进程 ID 4.进程运行时间 5.闹钟(定时器) 6.未决信号集
重点注意!躲避父子进程共享全局变量的知识误区!

【重点】:
父子进程共享:1. 文件描述符(打开文件的结构体)
2. mmap建立的映射区 (进程间通信详解)

特别的,fork之后父进程先执行还是子进程先执行不确定。取决于内核所使用的调度算法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值