linux编程实践:如何在一个程序的内部启动另一个程序?

我们可以在一个进程的内部启动另一个程序,从而创建一个新的进程。这个工作可以通过库函数的system来完成,可以‘ man 3 system’获取帮助。

#include<stdlib.h>
#include<stdio.h>
int main(){
    printf("Running ps with system\n");
    system("ps ax");
    printf("Done.\n");
    exit(0);
}

编译“systeml.c”文件,运行:

root@iZ2zecwg27cog23tyl7z4eZ:~/pro# ./systeml 
Running ps with system
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:04 /sbin/init noibrs splash
    2 ?        S      0:00 [kthreadd]
    4 ?        I<     0:00 [kworker/0:0H]
    6 ?        I<     0:00 [mm_percpu_wq]
    7 ?        S      0:02 [ksoftirqd/0]
    8 ?        I      1:07 [rcu_sched]
    9 ?        I      0:00 [rcu_bh]
   10 ?        S      0:00 [migration/0]
   11 ?        S      0:02 [watchdog/0]
   12 ?        S      0:00 [cpuhp/0]
   13 ?        S      0:00 [kdevtmpfs]
   14 ?        I<     0:00 [netns]
   15 ?        S      0:00 [rcu_tasks_kthre]
   16 ?        S      0:00 [kauditd]
   17 ?        S      0:00 [khungtaskd]
   18 ?        S      0:00 [oom_reaper]
   19 ?        I<     0:00 [writeback]
   20 ?        S      0:00 [kcompactd0]
   21 ?        SN     0:00 [ksmd]
   22 ?        I<     0:00 [crypto]
   23 ?        I<     0:00 [kintegrityd]
   24 ?        I<     0:00 [kblockd]
   25 ?        I<     0:00 [ata_sff]
   26 ?        I<     0:00 [md]
   27 ?        I<     0:00 [edac-poller]
   28 ?        I<     0:00 [devfreq_wq]
   29 ?        I<     0:00 [watchdogd]
   31 ?        I      0:14 [kworker/0:1]
   33 ?        S      0:00 [kswapd0]
   34 ?        I<     0:00 [kworker/u3:0]
   35 ?        S      0:00 [ecryptfs-kthrea]
   77 ?        I<     0:00 [kthrotld]
   78 ?        I<     0:00 [acpi_thermal_pm]
   79 ?        S      0:00 [scsi_eh_0]
   80 ?        I<     0:00 [scsi_tmf_0]
   81 ?        S      0:00 [scsi_eh_1]
   82 ?        I<     0:00 [scsi_tmf_1]
   88 ?        I<     0:00 [ipv6_addrconf]
   97 ?        I<     0:00 [kstrp]
  114 ?        I<     0:00 [charger_manager]
  152 ?        I      0:00 [kworker/0:2]
  153 ?        I<     0:01 [kworker/0:1H]
  173 ?        S      0:01 [jbd2/vda1-8]
  174 ?        I<     0:00 [ext4-rsv-conver]
  209 ?        S<s    0:03 /lib/systemd/systemd-journald
  250 ?        Ss     0:00 /lib/systemd/systemd-udevd
  271 ?        Ss     0:00 /lib/systemd/systemd-networkd
  294 ?        Ss     0:02 /lib/systemd/systemd-resolved
  336 ?        Ss     0:01 /usr/sbin/cron -f
  337 ?        Ssl    7:36 /usr/sbin/aliyun-service
  341 ?        Ss     0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --syst
  351 ?        Ss     0:00 /lib/systemd/systemd-logind
  388 ?        Ssl    0:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
  389 ?        Ss     0:00 /usr/sbin/atd -f
  390 ?        Ssl    6:02 /usr/local/aegis/aegis_update/AliYunDunUpdate
  391 ?        Ssl    0:15 /usr/lib/accountsservice/accounts-daemon
  394 ?        Ssl    0:00 /usr/sbin/rsyslogd -n
  402 ?        I<     0:00 [ttm_swap]
  452 ?        S      0:03 /usr/sbin/chronyd
  501 ttyS0    Ss+    0:00 /sbin/agetty -o -p -- \u --keep-baud 115200,38400,9600 ttyS0 vt220
  505 ?        S<sl  53:20 /usr/local/aegis/aegis_client/aegis_10_65/AliYunDun
  506 tty1     Ss     0:00 /bin/login -p --
  649 ?        Ss     0:00 /usr/sbin/sshd -D
  683 ?        Ss     0:00 /lib/systemd/systemd --user
  684 ?        S      0:00 (sd-pam)
  694 tty1     S+     0:00 -bash
  921 ?        I      0:00 [kworker/u2:2]
  965 ?        Ss     0:00 sshd: root@pts/0
 1007 pts/0    Ss     0:00 -bash
 1130 ?        Ss     0:00 sshd: root@pts/1
 1169 pts/1    Ss+    0:00 -bash
 1182 ?        I      0:00 [kworker/u2:1]
 1230 pts/0    S+     0:00 ./systeml
 1231 pts/0    S+     0:00 sh -c ps ax
 1232 pts/0    R+     0:00 ps ax
Done.
root@iZ2zecwg27cog23tyl7z4eZ:~/pro#

 

我们再来看一个创建进程的底层接口exec,“man 3 exec”获取帮助。

我们可以调用fork创建一个新进程,“man 2 fork”获取更多帮助信息。

简单的例子“forkl.c”

#include <sys/types.h>
#include <unistd.h>
#include<stdio.h>
#include<stdlib.h>
int main(){
    pid_t pid;
    char *message;
    int n;

    printf("fork program starting....\n");
    pid=fork();
    switch(pid){
        case -1:
            perror("fork failed");
            exit(1);
        case 0:
            message="This is the child";
            n=5;
            break;
        default:
            message="This is the parent";
            n=3;
            break;
    }
    for(;n>0;n--){
        puts(message);
        sleep(1);
    }
    exit(0);
}

 

当fork启动一个子进程时,子进程就有了它自己的生命周期并将独立运行。有时我们希望知道子进程何时结束。所以我们可以通过在父进程中调用wait函数,让父进程等待子进程的结束。参考“man 2 wait”获取更多信息。

还有另一个系统调用,可以用来等待子进程的结束,它就是waitpid函数,你可以用它来等待某个特定进程的结束。

 

 

 

 

REF:

C 库函数 – freopen() | 菜鸟教程  https://www.runoob.com/cprogramming/c-function-freopen.html

 

posted @ 2019-06-19 16:46  西伯利亚虎  阅读(1978)  评论(0编辑  收藏  举报

Permanence, perseverance and persistence in spite of all obstacles, discouragements and impossibilities: It is this, that in all things distinguishes the strong soul from the weak.