zoukankan      html  css  js  c++  java
  • 创建进程

    system系统调用

    #include <stdlib.h>

    int system(const char *string);

    system函数传递给/bin/sh –c 来执行string所指定的命令。
    string中可以包含选项和参数。
    如果没有找到/bin/sh,函数返回127,如果出现其他错误返回-1,成功返回0,但如果string为NULL,返回一个非0值。
     
     

    int main(void)

    {

      printf(“%d ”, system(“ls –l”));

      return EXIT_SUCCESS;

    }

    fork系统调用

    #include <unistd.h>

    pid_t fork(void);

    fork执行成功,向父进程返回子进程的PID,并向子进程返回0,这意味着fork即使只调用一次,也会返回两次。
    fork创建的新进程是和父进程(除了PID和PPID)一样的副本。
    父进程和子进程之间有点区别,子进程没有继承父进程的超时设置(使用alarm调用)、父进程创建的文件锁,或者未决信号。
    int main(void)
    {
        pid_t child = fork();
        if(child == -1)
        {
            printf("call fork error
    ");
            return -1;
        }
        if(child == 0)
        {
            printf("is child
    ");
        }
        else
        {
            printf("child pid is %d
    ",  child);
        }
        return 0;
    }
    你不能预计父进程是在它的子进程之前还是之后运行,它的执行是无序的,是异步的。
    fork的异步行为意味着你不应该在子进程中执行依赖与父进程的代码,反之亦然。
    fork调用可能失败,原因是系统上已经运行了太多进程,已经超过了允许它执行的最大进程数。
    fork执行失败,会向父进程返回-1,而且不创建子进程。
     
    fork过程包括把父进程全部内存映像复制给子进程,这个过程很缓慢。
    UNIX的设计者创建了vfork调用,vfork调用也创建新进程,但它不产生父进程的副本。
    Linux已经使用了写时复制技术,因此Linux的fork和UNIX的vfork一样快。
     
     

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

    fork创建了一个新的进程,产生一个新的PID。
    execve用被执行的程序完全替换了调用进程的映像。
    execve启动一个新程序,替换原有进程,所以被执行进程的PID不会改变。
    execve函数接受三个参数。
      –path-要执行的文件完整路径;
      –argv-传递给程序完整参数列表,包括argv[0],它一般是执行程序的名字;
      –envp-是指向执行execed程序的环境指针,可以设为NULL。
     

    int main(void)

    {

      char *args[] = { "/bin/ls", "-l", NULL };

      execve("/bin/ls", args, NULL);

      return 0;

    }

    用fork或者exec函数创建了一个新进程,为了收集新进程的退出状态并防止出现僵死进程(zombie process),父进程应该调用waitpid等待子进程的终止。
    什么是僵死进程?
      –一个僵死进程是在父进程有机会用wait或者waitpid收集它退出状态之前就终止的子进程。
      –之所以被称为僵死进程是因为他虽然死掉了,但依然在进程表中存在。
      –子进程退出后分配给它的内存和其他资源都被释放,但它还是在内核进程表中保留了一条,内核在父进程回收子进程的退出状态前一直保留它。
      –有一两个僵死进程不算什么问题,但一旦一个程序频繁执行fork或者exec却又不能收集退出状态,那么最终将会填满进程表,这会影响性能,可能导致系统重新启动。
     
    什么是孤儿进程(orphan process)
      –孤儿进程是一个父进程在调用wait或者waitpid之前就已经退出的子进程。此时init进程成为子进程的父进程。
      –init进程为子进程的父进程收集退出状态,从而避免出现僵死进程。
     
     
    wait和waitpid函数可以收集子进程的退出状态。

    #include <sys/wait.h>

    pid_t wait(int *status);

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

    stauts保存子进程的退出状态。
    pid为等待进程的PID,它能接受下表列出的4种值中的一个

    描述

    -1

    等待任何PGID等于PID的绝对值子进程

    1

    等待任何子进程

    0

    等待任何PGID等于调用进程的子进程

    >0

    等待PID等于pid的子进程

     
     
    options规定waitpid调用的行为应该如何。
       –WNOHANG-导致waitpid在没有子进程退出的时候立即返回;
      –WUNTRACED-意味着它应该因为存在没有报告状态的进程而返回。
     
     
     
    wait函数例子
    int main(int arg, char *args[])
    {
        pid_t pid = fork();
        int status;
        if (pid == -1)
        {
            printf("fork failed
    ");
            return 0;
        }
        if (pid == 0)
        {
            printf("child process start
    ");
            sleep(2);
            printf("child process end
    ");
            return 0;
        }
        else
        {
            printf("parent process start
    ");
            wait(&status);
            printf("parent process end
    ");
            return 0;
        }
    }

    waitpid函数例子

    int main(int arg, char *args[])
    {
        pid_t pid = fork();
        int status;
        if (pid == -1)
        {
            printf("fork failed
    ");
            return 0;
        }
        if (pid == 0)
        {
            printf("child process start
    ");
            sleep(2);
            printf("child process end
    ");
            return 0;
        }
        else
        {
            printf("parent process start
    ");
            waitpid(pid, &status, 0);
            printf("parent process end
    ");
            return 0;
        }
    }
     
     
     
     
  • 相关阅读:
    1323. Maximum 69 Number
    1217. Play with Chips
    1296. Divide Array in Sets of K Consecutive Numbers
    1288. Remove Covered Intervals
    1290. Convert Binary Number in a Linked List to Integer
    1295. Find Numbers with Even Number of Digits
    1306. Jump Game III
    1305. All Elements in Two Binary Search Trees
    1304. Find N Unique Integers Sum up to Zero
    浅谈 JSON.stringify 方法【转】
  • 原文地址:https://www.cnblogs.com/shichuan/p/4496177.html
Copyright © 2011-2022 走看看