C++项目实战-多进程(一篇文章)(一)

简介: C++项目实战-多进程(一篇文章)(一)

程序和进程的基本概念

程序: 是指编译好的二进制文件,在磁盘上,不占用系统资源。

        包含了一系列如何创建一个进程的信息。

       1.二进制格式标识:每一个程序文件的包含用于描述可执行文件格式的信息

                                       内核利用此信息来解释文件中的其他信息。

       2.机器语言指令:对程序算法进行编码

       3.程序入口地址:标识程序开始执行时的起始指令位置

       4.数据

       5.符号表及重定位表

       6.共享库和动态链接信息

       7.其他信息

进程:运行着的程序,在内存中,占用系统资源(cpu、文件描述符、锁...)

       进程是最基本的分配单位。进程可以看作是程序的一个实例。

单道程序设计和多道程序设计

单道程序设计:

       所有进程一个一个排队执行。

       

      如果A阻塞,B必须等待。A发生等待事件才会进入阻塞状态哦,所以此时A并没有占用CPU,那么就会导致CPU处于空闲状态。导致CPU资源的浪费(人们总是希望CPU能够永远不休息的工作)

多道程序设计:

       在计算机内存中同时存放多个独立的程序,上一篇文章讲到了虚拟地址空间,我个人认为,虚拟地址空间存在极大的方便了多道程序设计,虚拟地址空间相当于中间层,避免了直接使用内存而导致进程空间的不隔离、效率低、地址的不确定等问题。

       多道程序能够实现离不开时钟中断技术,这是在硬件上的机制,对于进程而言具有不可抵抗力。(CPU对于每一个进程而言是特别好吃的食物,没有哪个进程愿意主动的放弃CPU,只能降维打击)。操作系统通过中断处理函数来负责调度程序的执行。

       中断处理函数:是不是就会设计到怎么去实现。这个就是我们在学校学习操作系统时学习的一系列算法了,先来先服务、时间片轮转、短进程优先等等

并行和并发

前面说到了,多道程序设计...不可避免就会涉及到并发和并行的概念

并行:

       我们经常说,多核多核..其实说的就是处理器的数量,处理器即CPU。

       给大家看一下吧:

          8个

       一个CPU在同一时刻只能被一个进程使用,但是如果有两个CPU,同时就可以执行两个进程,那么这两个进程在同一时刻被同时执行,那么就称这两个进程时并行的

给大家画个图:

         

并发:

       我们说并行是站在多个CPU的角度,而我们讨论并发是站在一个CPU的角度。

       一个时间段,有多个进程都处于从开始运行到运行完毕的状态,但是每一个时刻只有一个程序在运行。

        CPU会产生很多时钟轮片分配给不同的进程。

在多道程序设计模型中,多个进程轮流使用CPU(分时复用CPU)。

形成"宏观并行,微观串行"

CPU处理速度是纳秒级别,一秒钟可以执行10亿条指令

进程控制块PCB

引入:在虚拟地址空间中,有个内核空间3G-4G(至于为什么是0-4G之前也讲过,因为32位平台下,指针占用4个字节,这么一来就限定了指针的寻址范围是0x00000000-0xFFFFFFFF 刚好对应0-4G),好像有点偏题了。我们回到内存空间,内核空间主要是冠以设备管理、进程管理、内存管理等一些内容,其中进程管理就是我们现在要关注的对象了,它是通过进程控制块也称为进程描述符来实现的,其实它就是一个结构体,结构体一个很重要的作用不就是实现数据封装吗....

所以说PCB就是一个结构体,里面包含了进程相关的一系列信息。

主要包含的信息:(理解不了就强制背下来)

进程id:唯一标识每一个进程(相当于学号),类型 pid_t,其实是int类型  (typedef int pid_t)

进程的状态:开始、就绪、阻塞、运行、终止

进程切换所需要保存的和恢复的现场信息:其实就是寄存器里的值

描述虚拟地址空间的信息

描述当前控制终端的信息

当前工作目录

umask掩码:保护文件权限

文件描述符表

信号相关信息

会话和进程组:守护进程会用到

用户ID和组ID

进程的资源上限: ulimit  -a

进程常用的命令

ps  aux / ajx

a:显示所有进程

u:显示进程的详细信息

x:显示没有控制终端的信息

j:显示与作用控制相关的信息

top(任务管理器)

实时显示进程动态

kill -l  显示所有信号

kill -9 进程ID    杀死某一个进程

环境变量

操作系统中指定操作系统运行环境的一些参数。char *[]数组,数组名environ,内部存储字符串,NULL作为结束标志。

你会发现里面配的是一些路径,我们在说动态库使用的时候有说过

如何使用:

需要先什么全局变量 environ    

extern  char ** environ;          

说白了就是这些全局变量放到了environ中,需要使用的话必须先声明

#include <iostream>
using namespace std;
extern char ** environ;
int main(void)
{
    for(int i=0;environ[i]!=NULL;++i)
    {
        cout<<environ[i]<<endl;
    }
    return 0;
}

常见的环境变量

PATH 可执行文件的搜索路径
SHELL 当前的shell
TERM 当前终端
LANG 语言
HOME 当前用户主目录的路径

环境变量操作函数

char * getenv(const char *name);

int  setenv(const char *name,const char *value,int overwrite);

int  unsetenv(const char *name);

#include <iostream>
#include <stdlib.h>
using namespace std;
int main(void)
{
    char * p = getenv("PATH");
    cout<<p<<endl;
    return 0;
}

进程控制

fork函数:创建一个子进程

pid_t fork(void);

失败返回 -1,成功父进程返回子进程的pid,子进程返回0

fork之后形成的父子进程关系,其实子进程只是把父进程的内容拷贝了一份。遵从"读时共享,写时复制"。这句话是说当父子进程有写操作的时候,就会单独给子进程映射一块物理内存,防止父子进程操作同一个数据而导致数据错误。注意这里说的是物理内存,不是虚拟内存,每一个进程都有一个自己的虚拟内存空间,这个是进程刚创建的时候操作系统就完成。

循环创建n个子进程

#include <unistd.h>
#include <iostream>
using namespace std;
int main(void)
{
    int i;
    for(i=0;i<3;++i)
    {
        pid_t pid = fork();
        if(pid == 0)
        {
            break;
        } 
    }
    sleep(i);
    if(i < 3)
    {
        printf("I am child:%d my parent:%d\n",getpid(),getppid());
    }
    else
    {
        printf("I am parent:%d\n",getpid());
    }
    return 0;
}

如果不让 pid==0及时的break,那么子进程和父进程在下一次循环都会frok..那么创建出来的进程数目 2^n

相关文章
|
2月前
|
资源调度 Linux 调度
Linux c/c++之进程基础
这篇文章主要介绍了Linux下C/C++进程的基本概念、组成、模式、运行和状态,以及如何使用系统调用创建和管理进程。
39 0
|
6月前
|
存储 调度 C++
【操作系统】进程与线程的区别及总结(非常非常重要,面试必考题,其它文章可以不看,但这篇文章最后的总结你必须要看,满满的全是干货......)
【操作系统】进程与线程的区别及总结(非常非常重要,面试必考题,其它文章可以不看,但这篇文章最后的总结你必须要看,满满的全是干货......)
131 1
|
6月前
|
存储 分布式数据库 API
技术好文:VisualC++查看文件被哪个进程占用
技术好文:VisualC++查看文件被哪个进程占用
|
2月前
|
消息中间件 Linux API
Linux c/c++之IPC进程间通信
这篇文章详细介绍了Linux下C/C++进程间通信(IPC)的三种主要技术:共享内存、消息队列和信号量,包括它们的编程模型、API函数原型、优势与缺点,并通过示例代码展示了它们的创建、使用和管理方法。
33 0
Linux c/c++之IPC进程间通信
|
2月前
|
Linux C++
Linux c/c++进程间通信(1)
这篇文章介绍了Linux下C/C++进程间通信的几种方式,包括普通文件、文件映射虚拟内存、管道通信(FIFO),并提供了示例代码和标准输入输出设备的应用。
30 0
Linux c/c++进程间通信(1)
|
2月前
|
Linux C++
Linux c/c++之进程的创建
这篇文章介绍了在Linux环境下使用C/C++创建进程的三种方式:system函数、fork函数以及exec族函数,并展示了它们的代码示例和运行结果。
40 0
Linux c/c++之进程的创建
|
7月前
|
C++ iOS开发
C++ 文件操作的技术性文章
C++ 文件操作的技术性文章
32 0
|
2月前
|
Linux C++
Linux c/c++进程之僵尸进程和守护进程
这篇文章介绍了Linux系统中僵尸进程和守护进程的概念、产生原因、解决方法以及如何创建守护进程。
23 0
|
4月前
|
存储 Serverless C++
【C++航海王:追寻罗杰的编程之路】一篇文章带你认识哈希
【C++航海王:追寻罗杰的编程之路】一篇文章带你认识哈希
19 0
|
6月前
|
存储 缓存 NoSQL
Redis系列学习文章分享---第十三篇(Redis多级缓存--JVM进程缓存+Lua语法)
Redis系列学习文章分享---第十三篇(Redis多级缓存--JVM进程缓存+Lua语法)
82 1