C/C++进程超详细详解【上部分】(系统性学习day06)

这篇具有很好参考价值的文章主要介绍了C/C++进程超详细详解【上部分】(系统性学习day06)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言

一、进程基础

1.进程概念

2.进程特征

3.进程状态(如图清晰可见)

4,进程的标识

实例代码如下:

5.进程的种类

实例shell脚本程序如下:

二、进程API

1.创建子进程

实例代码如下:

2.exec函数族

 函数族讲解图如下所示:

实例代码如下所示: 

3.结束进程

实例代码如下所示:

4.给进程收尸(释放进程占用的资源)

 wait实例代码如下:

waitpid实例代码如下: 

总结


前言

进程和线程的广泛意义是什么?

进程是计算机中运行的程序的实例。它具有独立的内存空间和资源,是操作系统分配和管理资源的基本单位。每个进程都拥有独立的地址空间、全局变量和文件打开等资源,进程之间相互独立。进程之间通常通过进程间通信(IPC)机制进行数据交互。

线程是进程中的一个执行单元。一个进程可以包含多个线程,这些线程共享进程的地址空间和资源,可以同时执行不同的代码路径。线程之间可以通过共享内存进行数据交换,因为它们可以访问相同的全局变量和堆内存。


一、进程基础

1.进程概念

进程是一个独立的可调度的任务
    (1)进程是一个抽象实体。当系统在执行某个程序时,分配和释放的各种资源
    (2)进程是一个程序的一次执行的过程
进程和程序的区别
    程序是静态的,它是一些保存在磁盘上的指令的有序集合,没有任何执行的概念
    进程是一个动态的概念,它是程序执行的过程,包括创建、调度和消亡
    进程是程序执行和资源管理的最小单位

2.进程特征

动态性 ----程序一次运行过程
并发性 ----可以同时运行多个进程
独立性 ----每个进程在各自独立的虚拟内存中运行
异步性 ----多个运行的进程之间相互没有关系

3.进程状态(如图清晰可见)

C/C++进程超详细详解【上部分】(系统性学习day06),Ubantu和C语言学习,开发语言,c语言,linux,学习

4,进程的标识

(1)主要的进程标识
    进程号(Process Identity Number,PID)
    父进程号(Parent Process ID,PPID)
    
(2)PID唯一地标识一个进程。可以通过以下两个函数获得:
    pid_t getpid(void)     //获取进程ID
    pit_t getppid(void)    //获取父进程ID

实例代码如下:

int main(void)
    {
        printf("pid = %d\n",getpid());
        printf("ppid = %d\n",getppid());
        return 0;
    }

 在终端运行的结果以及ps命令作用结果如下:

C/C++进程超详细详解【上部分】(系统性学习day06),Ubantu和C语言学习,开发语言,c语言,linux,学习

5.进程的种类

(1)交互进程:
    该类进程是由shell控制和运行的。交互进程既可以在前台运行,也可以在后台运行。
    
(2)批处理进程:
    该类进程不属于某个终端,它被提交到一个队列中以便顺序执行。

实例shell脚本程序如下:

        终端输入命令如下:

        touch test.sh
        chmod a+x test.sh  
        test.sh内容如下:
        ls
        touch 1.txt 2.txt 3.txt
        ls /
        cat fork1.c

 运行shell脚本文件如下:

     peter@ubuntu:~/2308/proc/day01_code$ ./test.sh
     1.txt  3.txt   exit.c   fork2.c   main.c    myproc.c  test.sh  wait.c   waitpid.c
     2.txt  exec.c  fork1.c  getpid.c  Makefile  test.c    wait     waitpid
     bin   cdrom  etc   initrd.img      lib    lost+found  mnt  proc  run   snap  swapfile  tftpboot         u  sr  vmlinuz
     boot  dev    home  initrd.img.old  lib64  media       opt  root  sbin  srv   sys       tmp                 var    vmlinuz.old
     #include <stdio.h>
     #include <sys/types.h>
     #include <unistd.h>

     int main(void)
     {
         fork();
         printf("hello world\n");
         return 0;
      }

 (3)守护进程:
          该类进程在后台运行。它一般在Linux启动时开始执行,系统关闭时才结束

二、进程API

1.创建子进程

pid_t fork(void);

fork调用过程:
    1,映射新的进程虚拟空间,该进程称为子进程。
    2,将父进程的各个数据段中的数据拷贝到子进程中
    3,父子进程共享代码段
    4,fork()调用过程返回两个值:
                  第一个值:给父进程返回子进程的ID号
                  第二个值:给子进程返回0
           调用失败返回:-1
    5,父子进程,从fork()调用的下一条语句同时运行   

实例代码如下:

void fun(void)
    {
        int i;
        for(i = 0 ; i  < 7; i++){
            printf("我是子进程,我要好好学习\n");
            sleep(1);
        }
    }

    int main(void)
    {
        int i;
        pid_t pid;

        if((pid = fork()) < 0){
            perror("fork");
            exit(1);
        }else if(!pid)
            fun();
        else
            for(i = 0 ; i  < 7; i++){
                printf("我是父进程,我要努力赚钱\n");
                sleep(1);
            }
        return 0;
    }

2.exec函数族

//加载另一个程序在进程的空间中执行
#include <unistd.h>
extern char **environ;

int execl(const char *path, const char *arg, ... /* (char  *) NULL */);
int execlp(const char *file, const char *arg,.../* (char  *) NULL */);
int execle(const char *path, const char *arg,../*, (char *) NULL,char * const envp[] */);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);

 函数族讲解图如下所示:

 C/C++进程超详细详解【上部分】(系统性学习day06),Ubantu和C语言学习,开发语言,c语言,linux,学习

实例代码如下所示: 

int main(void)
{
    int i;
    pid_t pid;

    if((pid = fork()) < 0){
        perror("fork");
        exit(1);
    }else if(!pid){   //子进程:执行另一个程序,如:ls
#if 0
        //execl("/bin/ls","ls","-l",NULL);
        //execlp("ls","ls","-l",NULL);
        char * arg[] = {"ls","-l",NULL};
        //execv("/bin/ls",arg);
        execvp("ls",arg);
#else
        //execl("/home/peter/2308/proc/day01_code/myproc","./myproc",NULL);
        char * env[] = {"name = peter","passwd = 123",NULL};
        //execle("/home/peter/2308/proc/day01_code/myproc","./myproc",NULL,env);
        char * arg[] = {"./myproc",NULL};
        execve("/home/peter/2308/proc/day01_code/myproc",arg,env);
#endif
    }else{   //父进程循环打印
        for(i = 0 ; ; i++){
            printf("我是父进程,我要努力赚钱\n");
            sleep(1);
        }
    }
    return 0;
}

3.结束进程

实例代码如下所示:

#include <stdlib.h>
void exit(int status);   //在结束进程之前,会先刷新缓冲,释放缓冲区,关闭打开的文件,然后再结束进程。

 #include <unistd.h>
 void _exit(int status);   //直接结束进程,不会刷新缓冲,释放缓冲区,关闭打开的文件
 //参数 ---status:  0-表示正常结束,非0-表示异常结束
 
 例如: 
 int main(void)
    {
        printf("hello world");

        //exit(1);     
        _exit(1);

        while(1);  
        return 0;     //在main函数中,执行return语句,return会调用exit()
    }

4.给进程收尸(释放进程占用的资源)

(1)wait
    #include <sys/types.h>
    #include <sys/wait.h>
    //作用:给任意一个子进程收尸
     如果子进程没有结束,则父进程会阻塞,直到子进程结束为止。
     如果父进程没有子进程,则wait函数立即返回。               
    pid_t wait(int *wstatus);   
    //参数  ----- 保存子进程结束状态的变量地址
    //返回值 ----成功:收尸的子进程的ID,失败:-1
    

 wait实例代码如下:

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


int main(void)
{
    int i;
    pid_t pid1,pid2;
    int status;

    if((pid1 = fork()) < 0){
	perror("fork");
	exit(1);
    }else if(!pid1){
	for(i = 0 ; i  < 7; i++){
	    printf("子进程1--pid = %d\n",getpid());
	    sleep(1);
	}
	exit(0);
    }
    if((pid2 = fork()) < 0){
	perror("fork");
	exit(1);
    }else if(!pid2){
	for(i = 0 ; i  < 3; i++){
	    printf("子进程2--pid = %d\n",getpid());
	    sleep(1);
	}
	exit(120);
    }
    if(wait(&status) < 0){
	perror("wait");
	exit(1);
    }
    printf("给子进程收完尸\n");
    printf("status = %d\n",WEXITSTATUS(status));
    return 0;
}

 (2)waitpid
    //作用:给指定的进程收尸
    pid_t waitpid(pid_t pid, int *wstatus, int options);
    //参数1  ---pid:
                pid > 0   给进程号为pid的子进程收尸
                pid = -1  与wait()相同,给任意子进程收尸
                pid = 0   给与当前进程在同一个进程组的中任意子进程收尸
                pid < -1  给进程组ID为|pid|的进程组中任意子进程收尸
    //参数2 ----保存子进程结束状态的变量地址
    //参数3 ---- 选项,一般为0

waitpid实例代码如下: 

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


int main(void)
{
    int i;
    pid_t pid1,pid2;
    int status;

    if((pid1 = fork()) < 0){
	perror("fork");
	exit(1);
    }else if(!pid1){
	for(i = 0 ; i  < 7; i++){
	    printf("子进程1--pid = %d\n",getpid());
	    sleep(1);
	}
	exit(234);
    }
    if((pid2 = fork()) < 0){
	perror("fork");
	exit(1);
    }else if(!pid2){
	for(i = 0 ; i  < 3; i++){
	    printf("子进程2--pid = %d\n",getpid());
	    sleep(1);
	}
	exit(120);
    }
    if(waitpid(pid1,&status,0) < 0){
	perror("wait");
	exit(1);
    }
    printf("给子进程收完尸\n");
    printf("status = %d\n",WEXITSTATUS(status));
    return 0;
}


总结

      本篇文章针对进程线程进行超详细讲解,希望能够帮到大家!

       以后还会给大家展现更多关于嵌入式和C语言的其他重要的基础知识,感谢大家支持懒大王!

       希望这篇博客能给各位朋友们带来帮助,最后懒大王请来过的朋友们留下你们宝贵的三连以及关注,感谢你们!文章来源地址https://www.toymoban.com/news/detail-716148.html

到了这里,关于C/C++进程超详细详解【上部分】(系统性学习day06)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 初识C语言——详细入门(系统性学习day4)

    目录 前言 一、C语言简单介绍、特点、基本构成 简单介绍: 特点: 基本构成: 二、认识C语言程序 标准格式: 简单C程序: 三、基本构成分类详细介绍    (1) (2)数据类型 计算机中常用存储单位 数据类型的取值范围 打印输入类型 (3)常量和变量 常量的分类:

    2024年02月08日
    浏览(37)
  • C/C++ 线程超详细讲解(系统性学习day10)

    目录 前言 一、线程基础 1.概念  2.一个进程中多个线程特征 2.1 线程共有资源 2.2 线程私有资源   3.线程相关的api函数  3.1 创建线程 创建线程实例代码如下:  需要特别注意的是: -lpthread和-pthread的区别 3.2 给线程函数传参   传参实例代码如下: 3.3 给线程收尸 收尸实例代码

    2024年02月08日
    浏览(36)
  • C/C++运算符超详细讲解(系统性学习day5)

    目录 前言 一、运算符的概念与分类 二、算术运算符 三、关系运算符  四、逻辑运算符 五、赋值运算符 六、运算符的优先级  总结   本篇文章是对运算符的具体讲解。 概念: 运算符就是一种告诉编译器执行特定的数学或逻辑操作的符号,用来表示针对数据的特定操作,也

    2024年02月07日
    浏览(40)
  • C/C++ stm32基础知识超详细讲解(系统性学习day14)

    目录 前言 一、ARM和STM32是什么? 二、STM32的开发方式 三、GPIO----寄存器开发方式 1.八种输入输出模式分析 2.寄存器  四、stm32芯片图片 五、怎么学好stm32  总结 stm32的广泛含义及背景: STM32是一款由意法半导体(ST)公司开发的32位微控制器,其全称是意法半导体32位系列微控

    2024年02月04日
    浏览(42)
  • C/C++网络编程基础知识超详细讲解第二部分(系统性学习day12)

                懒大王感谢大家的关注和三连支持~       目录 前言 一、UDP编程 UDP特点:  UDP框架: UDP函数学习   发送端代码案例如下: 二、多路复用  前提讲述 select  poll 三、图解如下  总结         作者简介:  懒大王敲代码,正在学习嵌入式方向有关课程stm32,网络

    2024年02月07日
    浏览(74)
  • C/C++网络编程基础知识超详细讲解第一部分(系统性学习day11)

    目录 前言 一、网络的含义与构成 含义: 构成:  二、网络的体系结构 1OSI七层模型 2TCP/IP协议体系结构  3数据经过体系结构,怎么封装?  4端口号 5大小端序 6TCP/UDP传输层的协议  三、系统函数API学习框架(TCP)     服务器(优先):  客户端: 四、服务器和客户端代码实

    2024年02月08日
    浏览(50)
  • vim的使用介绍以及命令大全(系统性学习day3)

                                                                                        懒羊羊感谢大家的关注和三连支持~  目录 前言 一、vim的使用介绍 二、命令大全 1.命令模式 (1)复制(配合粘贴命令p使用) (2)剪切 (3)粘贴 (4)删除 (5)撤销/恢复  (

    2024年02月08日
    浏览(40)
  • HarmonyOS4.0系统性深入开发19进程模型概述

    HarmonyOS的进程模型: 应用中(同一包名)的所有UIAbility运行在同一个独立进程中。 WebView拥有独立的渲染进程。 基于HarmonyOS的进程模型,系统提供了公共事件机制用于一对多的通信场景,公共事件发布者可能存在多个订阅者同时接收事件。 HarmonyOS通过CES(Common Event Service,公

    2024年01月19日
    浏览(44)
  • 【基础类】—面向对象类系统性学习

    构造函数模拟一个类 ES6 Class声明 通过 new 实例化一个类 借助构造函数实现继承 缺点: Parent1的原型上的属性和方法,并没有被child所继承。 总结:只实现了部分继承,如果父类的属性都在构造函数里面,完全可以实现继承,如果父类的原型对象上还有方法或属性,那么子类

    2024年02月14日
    浏览(46)
  • 如何系统性的学习Python语言

    零基础同学的福音来了,如果你对Python语言的学习感兴趣,接下来可以由浅入深的了解下Python语言,哪怕你是零基础的小白也完全可以学会的,最后也会给大家放出学习和实例相结合的教程及方法,给到各位同学系统性的教学,最重要的是免费,可真谓是学生党们的福音呀。

    2024年02月10日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包