zoukankan      html  css  js  c++  java
  • Linux下C进程管理(fork,wait,exec)

    在我们编程中用的最多是函数,也就是如何函数调用。那我们如何调用函数呢?
    一:我们必须要知道函数的功能是什么?
    二:再看这个函数需要哪些参数?
    三:最后看返回值是什么?
    当我们面对一个函数时,既不知道函数的功能也不参数以及返回值时,我们该如何下手呢?
    必须得动手查询呗,可以使用函数手册,终端,以及书本资料等、
    现在就用fork,wait,exec来举例说明:
    fork
    功能:创建一个新的进程

    一个现存进程调用fork函数是linux内核创建一个新进程的唯一方法(交换进程、init进程和页精灵进程并不是这样,这些进程是由内核作为自举过程的一部分以特殊方式创建的)。

    参数pid_t fork(void);
    返回值:一个是子进程返回0,第二个是父进程的返回值大于0.错误返回-1.
    头文件:include<unistd.h>
    wait
    功能:等待进程
    参数
    pid_t wait(int*status);返回值:调用成功,返回子进程的PID,发生错误返回-1。错误原因放在全局变量errno中
    头文件

    #include<sys/types.h>

    #include<sys/wait.h>
    waitpid
    函数说明:

    在一个子进程结束之前,wait使其调用者阻塞,waitpid使用WNOHANG参数以非阻塞方式等待子进程,waitpid可以指定所需要等待的子进程。

             pid == - 1 等待任一子进程。于是在这一功能方面waitpid与wait等效。

             pid > 0 等待其进程 I D 与 p i d 相等的子进程。

             pid == 0 等待其组 I D 等于调用进程的组 I D 的任一子进程。

             pid < - 1 等待其组 I D 等于 p i d 的绝对值的任一子进程。
    函数原型:

    pid_twaitpid(pid_t pid, int *status, int options);

    返回值:
    执行成功,返回PID为状态改变的子进程。如果指定了WNOHANG,pid参数所代表的子进程没有发生状态变化,0会被返回。执行失败返回-1。错误原因存放在errno中。
    头文件:

    #include<sys/types.h>

    #include <sys/wait.h>

    exec

    功能:在用f o r k函数创建子进程后,子进程往往要调用一个e x e c函数以执行另一个程序

    当进程调用一种e x e c函数时,该进程完全由新程序代换,而新程序则从其m a i n函数开始执行。因为调用e x e c并不创建新进程,所以前后的进程I D并未改变。e x e c只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。
    函数原型

    int execl( constchar *path, const char *arg, ...);

    int execlp(const char *file, const char *arg, ...);

    int execle(  const char  *path, const char *arg ,..., char * const envp[]);

    int execve(constchar * pathname char *const a rgv [], char *const envp []);

    int execv( constchar *path, char *const argv[]);

    int execvp(const char *file, char *const argv[]);

    巧记

    E:指可以传递环境变量表

    L:单独的参数传递,最后要有一个NULL

    V:传一个指针数组名

    P:按照环境变量来查找



    范例:

    char*ps_argv[]={“ps”,”ax”, NULL};

    char*ps_envp[]={“PATH=/bin:/usr/bin”,”TERM=console”, NULL}

    execl(“/bin/ps”,“ps”, “ax”, NULL);

    execv(“/bin/ps”,ps_argv);

    execle(“/bin/ps”,“ps”, “ax”, NULL, ps_envp);

    execve(“/bin/ps”,ps_argv, ps_envp);

    execlp(“ps”,“ps”, “ax”, NULL);

    execvp(“ps”,ps_argv);

    execl(“/bin/ps”,“ps”, “ax”, NULL);

    execlp(“ps”,“ps”, “ax”, NULL);

    execv(“/bin/ps”,ps_argv);

    execvp(“ps”,ps_argv);


    返回值:成功了没返回值,失败了返回-1.
    头文件
    #include<unistd.h>


    代码如下:
    #include<stdio.h>
    #include<unistd.h>
    #include<time.h>
    #include<sys/types.h>
    #include<sys/wait.h>
    #include<stdlib.h>
    #include<string.h>
    #define BUFSIZE 256
    int main(void)
    {
    pid_t pid;
    int i=0,j=0,m=0;
    char buf[BUFSIZE],cmd[BUFSIZE];
    char *argv[10]={NULL};
    char *gete=getenv("HOSTNAME");
    printf("%s",gete);
    while(1)
    {
    while(gete[m]!='.')
            {
                    buf[m++]=gete[m];
            }  
            printf("%s@%s%s",getenv("USER"),buf,getenv("PWD"));
            fgets(cmd,BUFSIZE,stdin);//stdin表示终端
    *strchr(cmd, '\n') = ' ';//strchr查找字符串中第一个出现的指定字符
    pid=fork();
    if(pid==-1)
    {
    perror("error!\n");
    //perror打印出错误原因信息字符串
    exit(-1);
    }
    else if(pid==0)
    {
    while (i < BUFSIZE && cmd[i] != '\0')
    {         if (cmd[i] != ' ')  {     argv[j++] = &cmd[i];
                         i = strchr(&cmd[i], ' ') - cmd; cmd[i] = '\0'; } i++;  }
    //通过while循环来截取需要的字符,字符串是以'\0' 结束的。
                execvp(argv[0], argv);
    perror("exec:");
                 exit(0);
    }
    else
    {
    waitpid(pid,NULL,0);
    }
    }
    return 0;
    }
  • 相关阅读:
    mac os 添加用户到组 命令
    mac下 codeigniter在apache下去掉index.php
    chrome的timeline中stalled问题解析
    Message Queue vs. Web Services?
    使用bootstrap框架的模态框与ckeditor产生冲突,ckeditor的弹出窗不可用时的解决方法
    file_get_contents微信头像等待时间过长的原因
    javascript学习笔记
    javascript学习笔记
    javascript学习笔记
    javascript学习笔记
  • 原文地址:https://www.cnblogs.com/robbychan/p/3786684.html
Copyright © 2011-2022 走看看