跟着iMX28x开发套件学linux-05

五、linux应用编程之三:进程基本操作

linux是一个多任务多用户的系统,可以同时运行多个程序。进程是正在被运行的程序,一个进程至少由一个或者多个线程组成。程序转变为进程的过程是:shell命令运行程序->系统寻找程序文件->fork()函数创建一个新进程->在新进程中用exec族函数装在main()函数。划重点,fork()建立新进程,exec装在程序。所有新进程在被内核创建时都会分配一个唯一的进程ID(PID),如果这个新进程有父进程的话,还会有父进程ID(PPID)。因为linux系统是多任务系统,而CPU的个数却是限定的,所以某个进程不能一直都在运行,要把CPU处理时间让给其他进程,因而进程有6种状态:不可中断的睡眠状态(D),运行或者准备就绪状态(R),可中断的睡眠状态(S),暂停状态(T),即将退出状态(X),僵尸进程状态(Z)。进程基本操作包括:创建进程,终止进程,用exec族函数加载不同的函数。

创建进程

1) 函数原型 pid_t fork(void);

2) 函数输入 无;

3)  pid_t,成功返回子进程的pid,失败返回-1

4)      pid_t  pid = fork();

5)      创建子进程成功后,父进程和子进程的代码是一样的,而且父进程和子进程都是运行态。唯一不同的是,在子进程中fork()返回的值是0,而父进程中fork()的返回值是子进程的pid,所以在代码中可以用if判断pid的值是否等于0,判断成立的代码段就是子进程要运行的代码段,判断不成立的代码段就是父进程要运行的代码段。

终止进程

1) 函数原型 正常终止void exit(int status);/异常终止abort()函数

2) 函数输入 status,终止状态,正常终止可以写0

3) 

4)      exit(0);

5)   1 return 0;实际上也是调用了exit(0);

6)   2 : 如果子进程终止的时候,父进程没有为其运行wait()函数,则子进程将变成僵尸进程,一直占用系统资源无法终止。所以父进程中一般要加上if(wait(&statue) != pid)来判断子进程是否可以终止,分析statue的状态可以知道是正常终止还是异常终止。wait()函数原型为:pid_t wait(int *status);,意思是等待接收子进程的终止状态,程序会卡在这个函数,知道子进程终止或出错。

exec族函数

调用exec族函数可以调用可执行文件,在子线程中可以调用exec族函数加载另一个程序运行。exec族函数一共有6个函数,作用是一样的,只是使用语法和规则有细微差别。

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

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

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

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

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

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

因为暂时还没使用过传递环境变量,所以e结尾的两个函数暂时先不用。

观察发现所有函数都是exec开头的,只是后面一位或者两位字母有区别。实际上,后缀有l表示加载程序时以列表(变元)形式输入参数,参数就一次写在括号内,以逗号间隔。而后缀有v表示以指针的形式传递新程序的参数,即所有要输入的参数事先写到一个字符串数组里,然后调用函数的时候再引用字符串数组的指针。显然后缀l和后缀v是互斥的,不可能既是l又是v后缀有p表示调用函数的时候*file参数可以只写文件名而不写路径名,此时系统会从环境变量指定的路径中寻找该文件,如果既写了文件名,又写了路径名,则和没有后缀p一样。下图列举了6个函数的使用范例:

 

应该注意到的是,运行新程序时argv的第一个参数是文件名,argv[1]之后的值才是真正的参数。

综合实例:

在一个程序内创建一个子进程,然后在子进程中调用之前写好的file文件。

 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>


int main(){
    int statue;
    pid_t pid;
    pid = fork();        //creat child process
    
    if(pid == 0){                                                    //child process
        printf("here is child process,my pid = %d\n",getpid());
        execl("/mnt/file","file",NULL);
        exit(-1);
    }
    else if(pid > 0){                                                //parent process
        printf("here is parent process, my pid = %d\n", getpid());
        if(pid != wait(&statue)){
            printf("child process exit error\n");
            exit(-1);
        }
        printf("child process exit succeed\n");
        exit(0);
    }
    else
        printf("creat process fault\n");
    return -1;
}

 

 

 

 

运行结果:

 

 

 

posted on 2018-11-05 20:36  diskiii  阅读(288)  评论(0编辑  收藏  举报

导航