zoukankan      html  css  js  c++  java
  • Linux系统编程:进程控制

    一、进程相关操作与编程对应函数

    1.进程创建:两种方式来实现。

    ①fork:创建一个子进程,父子进程共享一份代码程序,但是各有一份独立的数据,为了效率和保持数据的独立采用写时复制技术(COW)。运行无优先级。

    #include <unistd.h>
    pid_t fork(void);
    

    返回值:成功——子进程(0),父进程(子进程pid)、失败——(-1)

    ②vfork:创建一个新进程,子进程复制一份父进程的数据和堆栈空间(COW技术),继承父进程的用户代码、用户组、环境变量、打开的文件等资源,但是子进程不会继承父进程的文件锁定和未处理的信号。子进程优先执行,直到子进程调用exec函数或退出。在调用exec或exit之前,子进程和父进程的数据是共享的。

    #include<unistd.h>
    pid_t vfork(void);
    

    返回值:成功——子进程(0),父进程(子进程pid)、失败——(-1)

    2.进程等待

    ①wait:直到有信号来到或所有子进程结束时父进程才恢复执行。如果在调用wait()时子进程已经结束,则wait()会立即返回子进程结束状态值status。

    #include<sys/types.h>
    #include<sys/wait.h>
    pid_t wait (int * status);
    

    返回值:成功——子进程PID,失败——(-1)

    ②waitpid:指定等待的进程。

    #include<sys/types.h>
    #include<sys/wait.h>
    pid_t waitpid(pid_t pid,int * status,int options);
    
    Pid:欲等待的子进程识别码
        pid <-1 等待进程组识别码为pid绝对值的任何子进程。
        pid =-1 等待任何子进程,相当于wait()。
        pid = 0 等待进程组识别码与目前进程相同的任何子进程。
        pid > 0 等待任何子进程识别码为pid的子进程
    options 通常设置成0
    参数解释

    返回值:成功——子进程PID,失败——(-1)

    3.执行程序

    ①exec函数族:在当前的进程中执行任务。

    主要函数:execl、execv 、execle 、execve 、execlp 、execvp。函数的主要区别在于参数传递方式的不同

    "l" : list,函数的参数是通过一一列举的方式来传递的
    "v" : vector,向量、指针的意思,参数是通过字符数组指针来传递
    "e" : environment
    "p" : PACH,指定文件默认从PATH 环境变量中查找文件并执行
    函数字母含义
    #include<unistd.h> 
    /*
     *执行参数path字符串所代表的文件路径,接下来的参数,代表执行该文件时传递过去的argv(0)、argv[1]……,最后一个参,数必须用空指针(NULL)作结束。
    */
    int execl(const char *path,const char *arg,...);
    
    /*
     *执行参数path字符串所代表的文件路径,与execl()不同的地方在于execv()只需两个参数,第二个参数利用数组指针来传递给执行文件, char *const argv[]是指针数组,argv[0]、argv[1]...存放的是字符串的起始地址,这里要求他的最后一个成员存放的是NULL
    */
    int execv(const char *path,char *const argv[]);
    
    //从PATH环境变量指定的目录中查找符合file指针指向的字符串的文件来执行
    int execlp(const char *file,const char *arg,...);
    
    int execle(const char *path,const char *arg,...,char *const envp[]);
    int execve(const char *path,char *const argv[],char *const envp[]);
    int execvp(const char *file,char *const argv[]);
    函数用法解析

    返回值:失败——(-1)

    const char *argv[]={"ps","-au",NULL};
    const char *envp[]={"PATH=/bin/:/usr/bin:usr/local/bin","HOME=/home/clbiao/arm",NULL};
    //执行文件位置在第一个参数,执行参数在后面指出
    execl("/bin/ps","ps","-au",NULL);
    execv("/bin/ps",argv);
    //指定参数并指定搜索位置
    execve("/bin/ps",argv,envp);
    execle("/bin/ps","ps","-aux",NULL,envp);
    //只指定参数,从系统默认的PATH中搜,不用自己去定义envp
    execvp("ps",argv); 
    execlp("ps","ps","-au",0);
    识记方法

    ②system函数:在当前进程再创建一个进程来执行任务,是对fork、exec、waitpid的进一步封装。

    #include <stdlib.h>
    int system(const char *cmdstring);
    

    4.进程终止

    ①exit:退出进程前检查文件的打开情况,把打开的文件写回

    #include <stdlib.h>
    void exit(int status);
    

    ②_exit:直接退出进程,不处理标准I/O缓冲区

    #include <unistd.h>
    void _exit(int status);//status是返回给父进程的状态
    

    二、演示程序

     1 #include <unistd.h>
     2 #include <stdlib.h>
     3 #include <stdio.h>
     4 int main()
     5 {
     6     int pid;
     7     pid = vfork();
     8     //pid = fork();
     9     if(pid==0)
    10     {
    11         printf("
    Child process
    ");
    12         printf("This is in output buffer A");
    13         _exit(0);
    14     }
    15     else
    16     {
    17         printf("
    Father process
    ");
    18         printf("This is in output buffer B");
    19         exit(0);
    20     }
    21 }
    Test Code
    //使用vfork时是:
    Child process
    This is in output buffer A
    Father process
    This is in output buffer B
    //使用fork时是:
    Child process
    Father process
    This is in output buffer B
    运行结果

    结果分析:

        使用vfork时,子进程先执行,“Child process”先打印出来,接着把“This is in output buffer B”写到printfbuffer,并没有打印出来,因为后面的_exit(0)直接忽略I/O缓冲区,不作任何处理。然而轮到父进程执行时,继续接着往printfbuffer里面写数据(因为父子共用进程空间)直到遇到“ ”,进行处理,所以还是会把之前子进程残留在缓冲区的数据写出来。使用fork时,父子独立的进程空即数据区,子进程执行到_exit()buffer没有打印出来的字符就放在那里不管了,一点都不负责任exit()就不同了,虽然buffer里面的字符串中没有" ",但是他在退出之前还是收拾了这个烂摊子 (注:printf函数把缓冲区中的数据打印出来的条件是遇到" "换行符)

    三、问题思考

    问1.什么情况下会导致vfork出来的进程死锁?

    答1.在子进程调用exec或exit之前,子进程的进一步运行要依赖于父进程的一些操作就会导致死锁

  • 相关阅读:
    POJ 3253 Fence Repair
    POJ 2431 Expedition
    NYOJ 269 VF
    NYOJ 456 邮票分你一半
    划分数问题 DP
    HDU 1253 胜利大逃亡
    NYOJ 294 Bot Trust
    NYOJ 36 最长公共子序列
    HDU 1555 How many days?
    01背包 (大数据)
  • 原文地址:https://www.cnblogs.com/lubiao/p/4732862.html
Copyright © 2011-2022 走看看