进程创建,进程终止

进程创建:

fork函数:

#include<unistd.h>

pid_t fork(void);

返回值:

子进程返回0,父进程返回子进程的进程id,出错返回-1.

fork之后,子进程是父进程的副本。子进程获得父进程数据空间、堆和栈的副本。值得注意的是,这是子进程所拥有的副本,父进程和子进程并不共享这些存储空间部分。也就是说,子进程对变量做出的改变并不影响父进程。 

下面是一段关于fork的简单代码

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>

int main()
{
  int ret = fork();
  if(ret<0) {
      printf("fork");
      return 1;
   }
  else if(ret == 0)
    printf("i am child:%d!,ret:%d\n",getpid(),ret);
  else
    printf("i am father:%d!,ret:%d\n",getpid(),ret);

  sleep(1);
  return 0;
}

fork之后是先执行父进程还是先执行子进程是不确定的,取决于内核所使用的调度算法。如果我们想要子进程先运行,可以让父进程先sleep,等到子进程结束后再执行父进程。

写时拷贝:通常,父子代码共享,父子不再写入时,数据也是共享的,当任意一方试图写入时,便以写时拷贝的方式各自拷贝一份副本。

fork常规用法:

1.一个父进程希望复制自己,使父子进程同时执行不同的代码段。例如:父进程等待客户端请求,子进程来处理请求。

 2.一个进程要执行一个不同的程序。例如:从fork返回之后,执行exec函数。

fork调用失败的原因:

 1.系统中有太对进程

 2.实际用户的进程数超过了限制。

vfork函数:

 vfork也用来创建子进程,而子进程和附近曾共享地址空间。fork的子进程具有独立的地址空间。

vfork保证子进程先进行,在它调用exec或exit之后父进程才有可能被调度。当子进程调用这两个函数中的任意一个时,父进程会回复运行。

进程终止:

进程退出场景:

 1.代码运行完毕,结果正确

 2.代码运行完毕,结果不正确

 3.代码异常终止


进程正常终止:五种

 1.从main函数返回

 2.调用exit函数

 3.调用_exit_Exit函数

 4.进程的最后一个线程在启动例程中执行return语句

 5.进程的最后一个线程调用pthread_exit语句

进程异常退出:三种

 1.调用abort函数

 2.进程接收到某些信号时。如:ctrl + c

 3.最后一个线程对取消请求做出相应。

不管进程如何终止,最后都会执行内核中的同一段代码。这段代码为相应进程关闭所有打开描述符,释放它所使用的存储器等

 :


猜你喜欢

转载自blog.csdn.net/weixin_36229332/article/details/79656472