• 进程控制程序设计


    fork():创建一个新进程
    #include <unistd.h>
    pid_t fork(void)
    返回值:子进程中返回0,父进程中返回子进程ID,出错返回-1。
    fork()函数用于从一个已存在进程中创建一个新进程,新进程称为子进程,原进程称为父进程,父子进程分别有各自的返回值,其中父进程的返回值是子进程的进程号,而子进程则返回0。使用fork函数得到的子进程是父进程的一个复制品,它从父进程处继承了整个进程的地址空间。地址空间:包括进程上下文、进程堆栈、打开的文件描述符、信号控制设定、进程优先级、进程组号等。子进程所独有的只有它的进程号,计时器等。因此,使用fork函数的代价是很大的。一般来说,在fork之后是父进程先执行还是子进程先执行是不确定的.这取决于内核所使用的调度算法。
    例程:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    int main(int argc, char *argv[])
    {
        pid_t pid;
        pid = fork();//fork()返回二次,子进程中返回0,父进程中返回子进程号
        //pid = -1;
        if(pid<0)
        {
            printf("fork error\n");
            exit(1);
        }
        if(pid==0)
        {
            sleep(1);
            printf("son fork\n");
            printf("son process,id=%d,son's father id=%d\n",getpid(),getppid());
            _exit(0);
        }
        else
        {
            //sleep(1);
            printf("father fork\n");
            printf("father process,id=%d,son's id=%d\n",getpid(),pid);
            _exit(0);
        }
    }

    vfork函数:创建一个新进程
    #include <unistd.h>
    pid_t vfork(void);
    返回值:子进程中返回0,父进程中返回子进程ID,出错返回-1。
    vfork函数用于创建一个新进程,而该新进程的目的是exec一个新程序。
    vfork和fork一样都创建一个子进程,但它并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用exec(或exit),于是也就不访问该地址空间。相反,在子进程中调用exec或exit之前,它在父进程的地址空间中运行。
    vfork与fork之间的另一个区别是:vfork保证子进程先运行,在它调用exec或exit之后,父进程才可能被调度运行。
    例程:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>

    int main(int argc, char *argv[])
    {
        pid_t pid;
        pid = vfork();//vfork()返回二次,子进程中返回0,父进程中返回子进程号
        if(pid<0)
        {
            perror("vfork");
        }
        if(pid==0)
        {
            sleep(1);
            printf("son fork\n");
            printf("son process,id=%d,son's father id=%d\n",getpid(),getppid());
            _exit(0);
        }
        else
        {
            //sleep(1);
            printf("father fork\n");
            printf("father process,id=%d,son's id=%d\n",getpid(),pid);
            exit(0);
        }
    }

    wait和waitpid函数
    #include <sys/wait.h>
    pid_t wait(int *status)
    pid_t waitpid(pid_tpid, int *status, int options)

    发出wait调用的进程会进入睡眠直到它的一个子进程退出或收到一个不能被忽视的信号时被唤醒.
    如果该调用进程没有子进程或他的子进程已经结束,该调用立即返回.调用返回时参数status中包含子进程退出时的状态信息.
    调用waitpid与wait的区别是waitpid等待由参数pid指定的子进程退出.

    对于waitpid函数中pid参数的作用解释如下:
    pid=-1: 等待任一子进程。
    pid>0:等待进程ID与pid相等的子进程
    pid=0:等待其组ID等于调用进程组ID的任一子进程
    pdi<-1:等待其组ID等于pid绝对值的任一子进程

    options参数使我们能进一步控制waitpid的操作。此参数可以是:
    WNOHANG:若由pid指定的子进程不立即可用,则waitpid不阻塞,此时返回值0。
    WUNTRACED:等待由pid指定的任一子进程状态发生状态,且其状态自暂停以来还未报告过,则返回其状态。
    0:同wait,阻塞父进程,等待子进程退出。

    exit函数
    #include <stdlib.h>
    void exit(intstatus)
    void _exit(intstatus)
    通常通过exit函数来终止进程.
    exit函数用来正常终止发出调用的进程的执行,并把参数status返回给父进程,而进程所有的缓冲区数据会自动写回并关闭未关闭的文件

    注意:exit和_exit的区别
    _exit()用来立刻结束目前进程的执行,并把参数status返回给父进程,此函数调用后不会返回,并且会传递SIGCHLD信号给父进程,父进程可以由wait函数取得子进程结束状态。_exit()不会处理标准I/O缓冲区,exit()更新缓冲区,并关闭未关闭的文件。



  • 相关阅读:
    基于NIO的同步非阻塞编程完整案例,客户端发送请求,服务端获取数据并返回给客户端数据,客户端获取返回数据
    NIO编程中buffer对象的理解以及API的使用
    使用简单工厂模式写一个简单的计算器!!!
    java数字转字符串前面自动补0或者其他数字
    jQuery Validate自定义金钱验证,是否为金额格式,保留两位小数,并支持千分制货币格式
    javade多任务处理之Executors框架(线程池)实现的内置几种方式与两种基本自定义方式
    【转】asp.net mvc webapi+angular.js案例
    【转】MVC5中的区域(Areas)
    【转】在ASP.NET MVC中,使用Bundle来打包压缩js和css
    scroll pagination.js数据重复加载、分页问题
  • 原文地址:https://www.cnblogs.com/qinkai/p/2429728.html
Copyright © 2020-2023  润新知