zoukankan      html  css  js  c++  java
  • 多进程编程之system()函数

    1、system函数:  

      使用函数system,在程序中执行一个shell命令字符串很方便。它是一个和操作系统紧密相关的函数,用户可以使用它在自己的程序中调用系统提供的各种命令,执行系统的命令行,其实也是调用程序创建一个进程来实现的。实际上,system函数的实现正是通过调用fork、exec、waitpid函数来完成的。system函数原型:

     1 #include <stdlib.h>
     2 
     3 int system(const char* cmdstring);
     4 
     5 /*源码,该源码没有对信号进行处理*/
     6 #include <sys/types.h>
     7 #include <sys/wait.h>
     8 #include <errno.h>
     9 #include <unistd.h>
    10 int system(const char * cmdstring)
    11 {
    12     pid_t pid;
    13     int status;
    14 
    15     if(cmdstring == NULL){      
    16          return (1);
    17     }
    18 
    19     if((pid = fork())<0){
    20             status = -1;
    21     }
    22     else if(pid = 0){
    23         execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
    24         _exit(127); //子进程正常执行则不会执行此语句
    25         }
    26     else{
    27            while(waitpid(pid, &status, 0) < 0){
    28                 if(errno != EINTER){
    29                     status = -1;
    30                     break;
    31                 }
    32             }
    33         }
    34         return status;
    35 }

    2、system函数的返回值:

      由于system是通过fork、exec、waitpid函数实现的,则system对返回值的处理分为三个阶段:

      阶段1 fork失败,返回-1;

      阶段2 调用/bin/sh拉起shell脚本,只要能够调用到/bin/sh,并且执行shell过程中没有被其他信号异常中断,都算正常结束。
        (比如:不管shell脚本中返回什么原因值,是0还是非0,都算正常执行结束。
        即使shell脚本不存在或没有执行权限,也都算正常执行结束。
        如果shell脚本执行过程中被强制kill掉等情况则算异常结束。)    

        如何判断阶段2中shell脚本是否正常结束?如何判断阶段2中,shell脚本是否正常执行结束呢?系统提供了宏:WIFEXITED(status)。如果WIFEXITED(status)为真,则说明正常结束。

      阶段3 如果shell脚本正常执行结束,将shell返回值填到status的低8~15比特位中;

        如何取得阶段3中的shell返回值?你可以直接通过右移8bit来实现,但安全的做法是使用系统提供的宏:WEXITSTATUS(status)。

    总结:

      判断一个system函数调用shell脚本是否正常结束的方法应该是如下3个条件同时成立
      (1)-1 != status 创建子进程成功
      (2)WIFEXITED(status)为真  子进程正常退出
      (3)0 == WEXITSTATUS(status)  shell命令执行成功

    例:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <sys/wait.h>
     4 int main(int argc, char **argv)
     5 {
     6         int status = 0;
     7         status = system("exit 44");
     8         if (status == -1) {
     9                 printf("fork failed
    ");
    10                 return 0;
    11         }
    12         if (WIFEXITED(status)) {
    13                 printf("normal exit status = %d
    ",WEXITSTATUS(status));
    14         }
    15         return 0;
    16 }
  • 相关阅读:
    如何控制input框!
    火车头采集器破解版
    记Angular与Django REST框架的一次合作(2):前端组件化——Angular
    拉勾网一些“震惊”的结论
    一个知乎重度用户眼中的知乎
    anthelion编译
    搜索引擎爬虫蜘蛛的USERAGENT大全
    Netty系列之Netty高性能之道
    python正则表达式
    Cookie的使用,详解,获取,无法互通、客户端获取Cookie、深入解析cookie
  • 原文地址:https://www.cnblogs.com/funblogs/p/7571321.html
Copyright © 2011-2022 走看看