进程

来源:互联网 发布:电脑编程多久学会 编辑:程序博客网 时间:2024/06/04 01:35
1. system
在Linux中,可以使用system函数启动一个新程序,从而创建了一个新进程,函数原型如下:
int system(const char *command);
system函数有点类似与在shell中执行一个命令,system会等待该命令执行结束,例如:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
        printf("Running ps with system\n");
        system("ps ax");
        printf("Done.\n");
        exit(0);
}
编译并运行该程序,结果如下:
Running ps with system
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:00 /sbin/init
...
 3126 pts/2    S+     0:00 ./test
 3127 pts/2    S+     0:00 sh -c ps ax
 3128 pts/2    R+     0:00 ps ax
Done.
因为system函数用一个shell来启动想要执行的程序,所以可以把这个程序放在后台执行,上面程序修改部分如下:
system("ps ax &");


2. fork
在Linux中,使用fork系统调用创建一个子进程,这个子进程是父进程的一个克隆,包括代码段,数据段,堆栈段以及寄存器。子进程同样也可以调用fork去创建它的子进程,这样就形成了一个进程树。一个进程只有一个父进程,但是可以有0或多个子进程。Linux启动时会创建一个init进程,init进程位于树的最顶端,它是所有进程的父进程。每个进程都有个进程标志符(PID),init进程的PID为1,fork函数原型如下:
pid_t fork(void);
fork实例如下:
#include <stdio.h>
#include <unistd.h>

int main(void)
{
        int i = 10;

        pid_t pid = fork();

        if (pid < 0) {
                return -1;
        }

        while (i--) {
                if (pid == 0) { /* child */
                        printf("AAA\n");
                } else {        /* parent */
                        printf("BBB\n");
                }
        }

        return 0;
}
fork函数执行之前,只有一个进程,fork函数执行之后,有两个进程。前面说过,子进程是父进程的一份克隆,当然也包括程序指令指针PC,所以即使子进程包含父进程的全部代码,子进程也不会从头开始执行,而也是从fork函数之后开始执行。同一段代码,那怎么区分谁是子进程谁是父进程呢,就是通过fork函数的返回值,fork函数返回给子进程的是0,返回给父进程的是创建子进程的PID,如果创建失败,返回给父进程的是-1。至于先执行父进程还是先执行子进程,这个不一定,要看具体的进程调度算法。
前面说过,每个进程都有个PID,可以使用getpid函数返回进程PID,使用getppid函数返回父进程的PID。

3. wait
fork系统调用创建了一个子进程,这样子进程就有了自己的生命周期并独立于父进程运行,有时父进程需要知道子进程运行是否结束,这就需要在父进程中调用wait函数,wait函数原型如下:
pid_t wait(int *status);
其中返回值为子进程的PID,参数status为子进程的返回值或exit函数的退出码,上面的函数修改后如下:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(void)
{
        int i = 10;

        pid_t pid = fork();

        if (pid < 0) {
                return -1;
        }

        while (i--) {
                if (pid == 0) { /* child */
                        printf("AAA\n");
                } else {        /* parent */
                        wait(NULL);
                        printf("BBB\n");
                }
        }

        return 0;
}
编译运行可知新程序后的输出就没有上面程序输出那么凌乱。

4. exit
exit系统调用用于进程的退出,函数原型如下:
void exit(int status);
也可以使用kill系统调用去杀死一个进程,这样也能达到进程退出的目的。

原创粉丝点击