Linux进程

进程概述

程序和进程的区别

  • 程序:存储在磁盘上的某个可执行文件
  • 进程:程序被执行后称为进程

命令ps -aux:查看系统中所有用户的进程状态

在这里插入图片描述

进程标识符

每个进程都有唯一的进程标识符,进程ID都是非负整数,大部分为int型,小部分为long int型。

  • 定义一个变量用来存放进程ID:pid_t pid
  • 获取当前进程pid:getpid()
  • 获取当前进程的父进程pid:getppid()
  • 当进程的pid = 0时,该进程成为交换进程,用来进程调度
  • 当进程的pid = 1时,该进程成为init进程,用来系统初始化

C语言程序的存储空间分配机制

14aec8025080f23ee80e8.jpeg)

  • 正文:代码段
  • 初始化的数据:数据段
  • 未初始化的数据:存放没有赋值的数据
  • 堆:malloc、calloc等开辟空间的地方
  • 栈:保存函数调用时的返回地址以及函数的局部变量开辟空间的地方

进程相关函数

创建进程函数fork()

在这里插入图片描述
创建子进程,并打印父进程和子进程的PID

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    int data = 20;

    pid_t pid;
    printf("current process pid is %d\n",getpid());

    pid = fork();//fork之后无法决定父子进程谁先执行,但都会执行相同的代码段而且父、子进程对数据段的操作不会相互影响

    if(pid == 0){
        data += 10;
        printf("this is child process,current process pid is %d,fork return pid is %d\n",getpid(),pid);
    }else if(pid > 0){
        printf("this is father process,current process pid is %d,fork return pid is %d\n",getpid(),pid);
    }else{
        printf("fork is fail\n");
        perror("fork");
        exit(-1);
    }

    printf("data is %d\n",data);

    return 0;
}

在这里插入图片描述

创建进程的另一个函数vfork()

在这里插入图片描述
创建子进程,父进程和子进程共用一块内存

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
 
int main()
{
    int data = 20;
 
    pid_t pid;
    printf("current process pid is %d\n",getpid());
 
    pid = vfork();//fork之后无法决定父子进程谁先执行,但都会执行相同的代码段而且父、子进程对数据段的操作不会相互影响
 
    if(pid == 0){
        data += 10;
        printf("this is child process,current process pid is %d,fork return pid is %d\n",getpid(),pid);
    }else if(pid > 0){
        printf("this is father process,current process pid is %d,fork return pid is %d\n",getpid(),pid);
    }else{
        printf("fork is fail\n");
        perror("fork");
        exit(-1);
    }
 
    printf("data is %d\n",data);
	 
    exit(0);  
}

在这里插入图片描述

进程退出函数

在这里插入图片描述

父进程等待子进程函数wait()

  • 父进程比子进程先结束会使子进程成为孤儿进程,当子进程成为孤儿进程后,init进程会收养子进程
  • 如果子进程退出时,父进程没有等待子进程退出,子进程就会成为僵尸进程(即该进程一直存储在内存中)在这里插入图片描述

可以通过一些宏来获取进程的退出状态

  • WIFEXITED(wstatus): 当子进程正常结束时返回为真
  • WEXITSTUTAS(wstatus):当WIFEXITED(status)为真时调用,返回状态码的低8位
  • WIFSIGNALED(wstatus): 当子进程异常结束时返回为真
  • WTERMSIG(wstatus): 当WIFSOGNALED(status)为真时调用,返回引起终止的信号代码

父进程等待子进程退,子进程退出的状态码被父进程收集

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
 
int main()
{
    int data = 20;
 
    pid_t pid;
    printf("current process pid is %d\n",getpid());
 
    pid = fork();
 
    if(pid == 0){
        printf("this is child process,current process pid is %d,fork return pid is %d\n",getpid(),pid);
        int cnt = 0;
        while(1){
            cnt++;
            sleep(1);
            printf("cnt is %d\n",cnt);
            if(cnt == 5){
                exit(6);  //进程退出状态为6
            }
        }
 
    }else if(pid > 0){
        printf("this is father process,current process pid is %d,fork return pid is %d\n",getpid(),pid);
        int state = 0;
        wait(&state);  //父进程等待子进程退出并获取子进程退出状态
        for(int i=0;i<WEXITSTATUS(state);i++){
            printf("fataher process collect child process exit state is %d\n",WEXITSTATUS(state));  //打印状态码
        }
    }else{
        printf("fork is fail\n");
        perror("fork");
        exit(-1);
    }
 
    return 0;
}

在这里插入图片描述

进程等待另一个进程函数waitpid()

在这里插入图片描述

让当前进程执行新程序函数exec族函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
创建子进程利用execl()函数执行新程序

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
 
int main()
{
    pid_t pid;
    pid = vfork();
 
    if(pid == 0){
        pid_t childPid;
        childPid = getppid();
        char *str;
        str = (char *)malloc(32*sizeof(char));
        sprintf(str,"The process ID calling the new program is %d",childPid);
 
        execl("./newProcedure","newProcedure",str,"jiangxiaoya",NULL);
 
    }else if(pid > 0){
        wait(NULL);
        printf("child process finished executing the new program\n");
 
    }else{
        printf("fork is fail\n");
        perror("fork");
        exit(-1);
    }
 
    return 0;
}

新程序newProcedure.c

在这里插入图片描述

在这里插入图片描述

执行一条命令并等待命令完成后执行原程序函数system()

system的实现原理(本质还是调用了execl()函数)
在这里插入图片描述
在这里插入图片描述
利用system()函数调用终端执行ls命令,并输出在终端上

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
 
int main()
{
    int ret;
    ret = system("ls");
    if(ret == -1 || ret == 127){
        perror("system");
        exit(-1);
    }
    return 0;
}

在这里插入图片描述

执行一条命令并等待命令完成后执行原程序函数popen()

在这里插入图片描述
利用popen()函数调用终端执行ls命令,并存放到文件filePopen.txt上

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
 
int main()
{
    char readBuf[1024] = {'\0'};
    FILE *fp;
    fp = popen("ls", "r");
 
    int readSize = fread(readBuf,1,1024,fp);
 
    int fd = open("./filePopen.txt",O_RDWR|O_CREAT,0600);
 
    write(fd,readBuf,readSize);
 
    return 0;
}

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值