• Linux fork创建子进程


    1.  pid_t fork(void);
      功能:创建父子进程
      参数:无
      返回值:成功:在父进程中:返回值为子进程的PID
        在子进程中:返回值为0
        失败:-1
    注意:
      1)fork函数是用来创建进程的,fork之后产生了两个进程,每个进程都会有返回值,
           所以父进程中返回的是子进程的进程号(>0);在子进程中返回0

      2)子进程几乎拷贝了父进程的全部内容。
            包括代码、数据、系统数据段中的pc值、栈中的数据、父进程中打开的文件等;但它们的PID、PPID是不同的。

      3)父子进程有独立的地址空间,互不影响;当在相应的进程中改变全局变量静态变量,都互不影响。

      4)若父进程先结束,子进程成为孤儿进程被init进程收养(此时子进程的父亲就是init),子进程变成后台进程。(init进程号为1)

      5)若子进程先结束,父进程如果没有及时回收,子进程变成僵尸进程(要避免僵尸进程产生)


    2.   pid_t getpid(void);
    功能:得到正在调用此接口的进程的进程号
    返回值:得到PID号

    3.   pid_t getppid(void);
    功能:得到正在调用此接口的进程的父进程号
    返回值:得到PID

    4.  pid_t wait(int *status)  头文件 <sys/types.h> <sys/wait.h>

    功能:阻塞等待任意子进程的结束,回收资源
    status是一个整型指针,指向的对象用来保存子进程退出时的状态。
    status若为空,表示忽略子进程退出时的状态
    status若不为空,表示保存子进程退出时的状态
    另外,子进程的结束状态可由Linux中一些特定的宏来测定。

    5.  pid_t waitpid(pid_t pid, int *status, int options)
    功能:等待子进程的结束,回收资源
    参数:
      (1)pid:
    pid>0:只等待进程ID等于pid的子进程,不管已经有其他子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。
    pid=-1:等待任何一个子进程退出,此时和wait作用一样。
      (2)status:同wait
      (3)options:WNOHANG:不阻塞,返回 0(没有接受到),pid号(成功接收到) 0:同wait,阻塞父进程,等待子进程退出。失败 -1 ,成功 pid号 
    返回值:
    正常:结束的子进程的进程号,使用选项WNOHANG且没有子进程结束时:0
    出错:-1
    等价:wait(NULL) == waitpid(-1, NULL, 0)
      WEXITSTATUS(status)


    6.  void exit(int status);
    功能:结束正在调用的进程,程序结束前,会清理缓存区

    7.  _exit:void _exit(int status);
    功能:结束正在调用的进程,程序结束前不清理缓存区
    注意:
    status是一个整型的参数,可以利用这个参数传递进程结束时的状态。
    通常0表示正常结束;其他的数值表示出现了错误,进程非正常结束。
    在实际编程时,可以用wait系统调用接收子进程的返回值,进行相应的处理。
    exit用于结束正在运行的整个程序,它将参数返回给OS,把控制权交给操作系统;
    而return 是退出当前函数,返回函数值,把控制权交给调用函数。

    fork创建子进程例子:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    int main(int argc, const char *argv[])
    {
        pid_t pid;
        pid = fork();
        if(pid == -1)//失败返回 -1
        {
            perror("fork fail : ");
            exit(1);
        }
        else if(pid == 0) //在子进程中:返回值为0 
        {
            printf("child
    ");
            printf("child getpid() %d 
    ",getpid());
            printf("child getppid() %d 
    ",getppid());
            exit(1);
        }
        else //在父进程中:返回值为子进程的PID
        {
            int s;
            wait(&s);
            printf("fork
    ");
            printf("father pid %d
    ",pid);//子进程pid
            printf("father getpid() %d 
    ",getpid()); //父进程pid
            printf("father getppid() %d 
    ",getppid());//父进程的父进程的pid
            printf("father %d
    ",WEXITSTATUS(s));
            perror((char*)&s);
        }
        return 0;
    }

    测试:

     子进程会复制父进程的全部内容,出来pid号和ppid号,但是子进程程序执行从 fork 函数之后执行的

  • 相关阅读:
    OC与Swift的区别二(常量、变量、运算符)
    OC与Swift的区别一(文件结构)
    OC对象的归档及解档浅析
    OC单例模式的实现
    oc文件基本读写及操作
    IOS之沙盒(Sandbox)机制
    IOS开发之KVC与KVO简述
    SpringMVC控制器配置文件
    spring常用的连接池属性文件配置
    Struts2文件上传方式与上传失败解决方式
  • 原文地址:https://www.cnblogs.com/electronic/p/10932717.html
Copyright © 2020-2023  润新知