zoukankan      html  css  js  c++  java
  • 程序、进程和线程

    程序是计算机指令的集合,以文件的形式存储于磁盘上。

    进程:通常被定义为一个正在运行的程序的实例,是一个程序在其自身地址空间的一次执行活动。

    一个程序可以有多个进程(如打开多个记事本程序),一个进程也可以同时访问多个程序。

    进程是资源申请、调度和独立运行的单位,因此,它使用的是系统的运行资源;而程序不是,不占用系统的运行资源。

    进程由两部分组成:

    1.操作系统用来管理进程的内核对象。内核对象:操作系统内部分配的一个内存块,数据结构,不能被应用程序直接访问,需通过windows提供的函数操作。

    2.地址空间。包含所有可执行模块或DLL模块的代码和数据,还包含动态内存分配的空间,如线程堆栈和堆分配空间。

    进程是不活泼的,从来不执行任何东西,只是线程的容器。若要是进程完成某项操作,必须有一个在它环境中运行的线程。此线程负责执行包含在进程地址空间的代码。(进程只是线程的执行环境

    单个进程可以包含多个线程,这些线程一起“同时”执行进程地址空间中的代码。

    每个进程至少拥有一个线程,来执行进程的地址空间的代码。当创建一个进程时,操作系统会自动创建该进程的第一个线程,称为主线程。此后,该线程可以创建其他的线程。

    进程地址空间

    系统赋予每个进程独立的虚拟地址空间。对于32位的进程来说,这个地址空间为4GB。

    每个进程有它自己的私有地址空间。如,进程A、B均在地址0x12345678上存有数据结构,但A不能访问B,B也不能访问A的数据结构。

    4GB是虚拟的地址空间,只是内存的一个范围。在能成功地访问数据不会出现非法访问之前,必须赋予物理存储器(物理内存+页文件),或将物理存储器映射到各个部分的地址空间。

    4GB虚拟地址空间中,2GB是内核方式分区,供内核代码、设备驱动程序、设备I/O高速缓冲、非页面内存池的分配和进程页面表的使用呢等,而用户分区使用的地址空间为2GB-64KB,此分区为进程的私有地址空间所在的地方,一个进程不能读取、写入或者以任何方式访问驻留在该分区的另一个进程的数据,对于所有的应用程序来说,该分区是维护进程大部分数据的地方。其余的64KB地址空间为空指针使用的分区。

    线程的构成:

    1.线程的内核对象。操作系统用它对线程实施管理。

    2.线程堆栈。用于维护线程在执行代码时所需要的所有参数和局部变量。

    image

    线程运行

    操作系统为每一个运行的线程安排一定的CPU时间--时间片。线程在自己的时间段内运行,时间片终止的话,操作系统就会选择另外一个线程继续运行。

    系统通过一种循环的方式为线程提供时间片,线程在自己的时间片内运行,时间片很短,给用户的感觉就是同时运行一样。

    如果计算机拥有多个CPU,线程就能真正意义上的同时运行。

    关于多进程和多线程

    多线程好处:每个线程均独立的完成一个任务。移植到多CPU后,就可以并发运行

    使用多进程的话,每个进程需系统分配私有的4GB的虚拟地址空间。多线程共享同一进程的地址空间。

    互斥对象(唯一一个与线程内核相关的对象:可将互斥对象的ID设为线程ID

    互斥对象(mutex)属于内核对象,它能够确保线程拥有对单个资源的互斥访问权

    互斥对象包含一个使用数量,一个线程ID和一个计数器

    ID用于标识系统中哪个线程当前拥有互斥对象,计数器用于指明该线程拥有互斥对象的次数

    互斥对象作用:一个线程在一个时间段内对一种资源进行的访问的时候,其他的线程不能在该时间段内对该资源进行访问

                          (包含共享资源)

    ReleaseMutex不能释放不同线程的互斥对象;通过判断线程与互斥对象的ID是否相等,不等则不能释放

    哪个线程拥有互斥对象,就应该是那个线程去释放该互斥对象。

    互斥对象保护全局变量

    结果线程交替:

    image

    操作系统会在某线程结束后,会自动将线程所拥有的互斥对象的线程ID设为0,并将级数清零。操作系统维护了线程和与线程相关的互斥对象的信息,知道是哪个线程终止,并清理。

    命名的互斥对象(只运行一个实例

    hMutex = CreateMutex(NULL,TRUE,"tickets"); //若此处不具名,则后面不起作用
        if (hMutex)
        {
            if (ERROR_ALREADY_EXISTS == GetLastError() )
            {
                cout<<"only one instance can run!"<<endl;
                return ;
            }
        }


     

  • 相关阅读:
    使用SignTool对软件安装包进行数字签名(二)--进行数字签名
    使用SignTool对软件安装包进行数字签名(一)--制作证书
    三角形相关算法--求解三角形顶点坐标
    子网掩码与子网个数、主机地址个数的关系
    pgsql中的lateral使用小结
    Git中rebase失败了如何进行恢复
    灰度发布
    go 中的WaitGroup
    pgsql中json格式数组查询结果变成了字符串
    Go中的unsafe
  • 原文地址:https://www.cnblogs.com/baiweiguo/p/3008712.html
Copyright © 2011-2022 走看看