• linux 进程控制笔记


    进程创建

    普通函数调用完成后,最多返回(return)一次,但fork/vfork会返回二次,一次返回给父进程,一次返回给子进程
    父进程的返回值为子进程的进程ID,子进程的返回值为0
    1.pid_t fork(void)
    父子进程共享代码段,fork之后子进程获得父进程数据空间、堆和栈的副本,然后各自独立操作自己的数据,但他们共享文件描述符

    2.pid_t vfork(void)
    父子进程共享资源不分家;子进程比父进程先运行,子进程结束后再运行父进程,像普通的函数调用一样

    进程同步

    1.pid_t wait(int *statloc)
    由父进程调用,阻塞式等待任一子进程结束

    2.pid_t waitpid(pid_t pid, int *statloc, int options)
    可以选择等待指定子进程结束,可设置成非阻塞式等待

    调用外部程序

    1.exec函数家庭
    exec函数族不创建新进程,只是用磁盘上的一个新程序替换了当前进程的正文段、数据段、堆和栈段
    特别注意的是exec执行成功时不返回(就是不再执行exec下面的语句),在载入的程序执行完后就退出了

    2.int system(char *cmdstring) 系统调用
    system适合拿来调用系统内置的命令或shell脚本

    进程优先级

    1.int nice(int incr)
    主动降低使用cpu的频率

    2.int getpriority(int which, id_t who)
    获取nice值

    3.int setpriority(int which, id_t who, int value);
    可以为进程、进程组和特定用户的所有进程设置优先级

    进程终止

    1.正常终止

    • 从main返回:return 0,关闭io流等资源文件
    • exit:同return 0
    • _exit:仅将自身设置成不可运行,由父进程调用wait/waitpid进行资源回收

    2.异常终止

    • abort:因特殊情况主动终止
    • 由一个信号终止:被其它程序kill或运行期间产生错误(越界内存访问/除零等)被系统中止

    例子

    1.wait/waitpid/fork基本用法

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
     
    int main(){
        pid_t pid;
        if((pid=fork()) <0){
            perror("fork error");
            return -1;
        }else if(pid==0){
            if(system("ls -l")<0){
                puts("system error");
                _exit(-1);
            }
            _exit(0);
        }
     
        if(waitpid(pid,NULL,0) != pid)
            puts("wait error");
     
        if((pid=fork()) <0){
            perror("fork error");
            return -1;
        }else if(pid==0){
            execlp("date","date",(char *)0);
            puts("if execlp goes wrong,you will see me!");
            _exit(-1);
        }
     
        if(wait(NULL)<0)
            puts("wait error");
     
        return 0;
    }
    

    2.退出状态

    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/wait.h>
     
    void pr_exit(int status){
        if(WIFEXITED(status))
            printf("normal exit, exit status=%d
    ",WEXITSTATUS(status));
        else if(WIFSIGNALED(status))
            printf("abnormal exit, signal number=%d
    ",WTERMSIG(status));
        else if(WIFSTOPPED(status))
            printf("child stoped, signal number=%d
    ",WSTOPSIG(status));
        else
            printf("unknown exit
    ");
    }
     
    int main(){
        pid_t pid;
        int status;
    //_exit
        if((pid=fork())<0){
            perror("fork error");
            return -1;
        }else if(pid==0)
            _exit(7);
     
        if(wait(&status) != pid){
            perror("wait error");
            return -1;
        }
        pr_exit(status);
    //abort
        if((pid=fork())<0){
            perror("fork error");
            return -1;
        }else if(pid==0)
            abort();
     
        if(wait(&status) != pid){
            perror("wait error");
            return -1;
        }
        pr_exit(status);
    //divide by 0   
        if((pid=fork())<0){
            perror("fork error");
            return -1;
        }else if(pid==0)
            status /=0;
     
        if(wait(&status) != pid){
            perror("wait error");
            return -1;
        }
        pr_exit(status);
     
        return 0;
    }
    
  • 相关阅读:
    docker pull报错failed to register layer: Error processing tar file(exit status 1): open permission denied
    PySocks安装使用方法
    PyInstaller Extractor安装和使用方法
    service docker start后docker stop/waiting的解决方法
    PyInstaller安装使用方法
    ubuntu安装docker-ce
    Python对wav文件的重采样
    Microsoft Speaker Recognition API
    通过google cloud API 使用 WaveNet
    NLP一些工程应用模型
  • 原文地址:https://www.cnblogs.com/cfans1993/p/5596890.html
Copyright © 2020-2023  润新知