进程创建

来源:互联网 发布:playingwithshiro软件 编辑:程序博客网 时间:2024/05/16 01:56
此文章转载于http://blog.chinaunix.net/uid-23193900-id-3193545.html
1.创建一个进程
 进程是系统中基本的执行单位(线程是最小的调度单位)。
linux系统允许任何一个用户创建一个子进程,创建之后,子进程存于系统之中,并且独立于父进程。该子进程可以接受调度,可以分配得到系统资源。
fork函数创建一个新的进程:
#include  <unistd.h>
pid_t fork(void);
 
注:系统中,除了0号进程以外(0号进程是由系统创建的),任何一个进程都是由其他进程创建的。
fork()函数不需要参数,返回一个进程ID。返回值有三种情况:
(1)对于父进程,fork函数返回新的子进程的ID。
(2)对于子进程,fork函数返回0。
(3)如果出错,fork函数返回-1。
 
fork函数创建一个新的进程,并从内核中为此进程得到一个新的可用进程ID,之后为这个新进程分配进程空间,并将父进程的进程空间中的内容复制到子进程的进程空间中,包括父进程的数据段+堆栈段,并与父进程共享代码段
 
fork函数之后,子进程从等待fork返回开始执行,而不是从头开始
 
2.父子进程的共享资源
子进程完全复制了父进程的地址空间的内容,包括堆栈段+数据段的内容。但是,子进程并没有复制代码段,而是和父进程共享代码段。代码段是只读的,不存在修改的问题,因此可以共用。
 
3.创建一个共享父进程空间的子进程
在创建一个子进程后,子进程的地址空间完全和父进程分开,父子进程是两个独立的进程。接受系统调度和分配系统资源的机会均等。父子进程完全分家,除了代码段这部分。
 
linux环境下提供一个和fork函数类似的函数,可以用来创建一个共用父进程地址空间的子进程。
pid_t  vfork();
 
vfork()与fork()的区别:
(1)vfork产生的子进程和父进程完全共享地址空间,包括代码段+数据段+堆栈段。子进程对共享资源进行的修改,也会影响到父进程。
(2)vfork函数产生的子进程一定比父进程先运行。即父进程调用了vfork函数后会等待子进程运行后再运行。
 
4.在函数内部调用vfork函数

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. #include <unistd.h>

  3. int f1()
  4. {
  5.     vfork();//create child process
  6.     return 0;
  7. }

  8. int f2(int a,int b)
  9. {
  10.     return a+b;
  11. }

  12. int main()
  13. {
  14.     int c;
  15.     f1();
  16.     
  17.     c=f2(1,2);
  18.     printf("%d\n",c);

  19.     return 0;

  20. }
上面的代码在f1函数中调用了vfork函数。
父进程在调用f1函数后,子进程先执行,所以子进程从f1中返回,由于栈共享,f1函数的栈帧随着子进程的执行被覆盖掉。子进程调用f2也没有错误。但当父进程从f1中返回时,f1()的栈帧已经被f2()覆盖了。所以父进程返回错误。
 
5.退出进程
linux环境下使用exit()函数退出
#include <stdlib.h>
void exit(int status);
exit()函数的参数表示退出的状态,这个状态的值是一个整型。在shell中可以检查到这个退出的状态值。

点击(此处)折叠或打开

  1. #include <stdlib.h>
  2. int main()
  3. {
  4.     exit(2);
  5. }

  6. #echo $?
  7. #2
return语句会被翻译成调用exit函数。
可以将errno变量作为参数返回。
exit(errno)。