多线程

多线程

进程和程序

进程:正在运行的程序的实例,是一个程序在其自身的地址空间中的一次执行活动

程序:计算机指令的集合,它以文件的形式存储在磁盘上

一个程序可以对应多个进程

进程是资源申请,调度和独立运行的单位

程序不能申请系统资源,不能被系统调度,也不能作为独立运行的单位

进程的组成

  内核对象:操作系统内部分配的一个内存块,用来存放关于进程的统计信息的地方,负责维护该对象的各种信息

地址空间:包含所有可执行程序模块或DLL模块的代码和数据,还包含动态内存分配的空间

内核对象的数据结构只能被内核访问使用,应用程序只能通过Windows提供的一些函数来对内核对象进行操作

真正完成代码执行的是线程,进程只是线程的容器,或者说是线程的执行环境

主线程:创建进程时,操作系统为此进程自动创建的第一个线程,执行main或Winmain函数

虚拟内存:页文件在磁盘上划分出一块空间当做内存使用

线程的组成

内核对象:操作系统用来它来对线程进行管理,存放线程统计信息

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

线程总是在某个进程环境中创建的,系统从进程的地址空间中分配内存,供线程的栈使用

新线程可以访问进程的内核对象的所有句柄、所有内存和相同进程中的所有其他线程的堆栈

线程只有一个内核对象和栈

线程运行:

操作系统为每个运行线程安排一定的CPU时间片

如果计算机拥有多个cpu时间片,线程就能真正意义上同时运行了

尽量采用多线程:

1.占用资源少

系统要为进程分配私有的4GB的虚拟地址空间,多线程是共享同一个进程的地址空间

2.效率高

进程切换,需要交换整个地址空间

线程切换,只是执行环境的改变

页面是系统管理内存时使用的内存单位

线程创建:

HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, //线程的安全性

DWORD dwStacksSize, //线程的栈的大小

LPTHREAD_START_ROUTINE lpStartAddress,//新线程的入口函数LPVOID lpParammeter, //入口函数的参数

DWORD dwCreationFlags,//控制线程创建的状态,挂起/运行

LPDWORD lpThreadId // 为线程分配的ID)

入口函数形式 DWORD WINAPI ThreadProc(LPVOID lpParameter)

CloseHandle函数并没有终止新创建的的线程,系统会递减该线程的使用计数

如果想让某个线程暂停,可以调用Sleep(int)函数

利用互斥对象实现线程同步:

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

包含一个使用数量,一个线程ID和一个计数器

HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,

BOOL bInitialOwner, //为false时,没有线程拥有它,有信号

LPCTSTR lpName

)

BOOL ReleaseMutex(HANDLE hMutex)

线程主动请求共享对象的的使用权:

WaitForSingleObject(HANDLE hHandle ,DWORD dwMilliseconds)

当指定对象变成有信号态或等待时间间隔已过

对互斥对象来说,谁拥有谁释放

当线程调用WaitForSingleObject请求该互斥对象的所有权时,如果请求的线程ID和当前拥有者的ID相同时,仍然能够请求到这个互斥对象,该互斥对象内部的计数器记录了该线程拥有的次数

可以根据WaitForSingleObject函数的返回值知道当前线程是如何得到互斥对象的所有权的

可以通过使用命名的互斥对象来实现应用程序只有一个实例运行的目的

主线程退出,意味着进程结束了

原文地址:https://www.cnblogs.com/xiaoxiaocaicai/p/3595325.html