windows基础编程 - 进程和线程

前言

 微软鼓励大家多用线程,而弱化子进程的使用,所以和unix不同,windows下进程的通信很少,内存映射文件是一种。

进程

  • 进程环境信息(进程上下文)

    每个进程启动时系统都会生成相关的环境表,获取里面的环境变量可使用下面函数
    GetEnvironmentStrings FreeEnvironmentStrings 可以获得该环境表的首地址
    SetEnvironmentVariable GetEnvironmentVariable 可以设置和得到环境变量的值

  • 获取进程ID和进程句柄
    GetCurrentProcessId 获取id
    GetCurrentProcess 获得句柄,但是一个假句柄,值为-1,可正常使用
    OpenProcess 通过id获得进程句柄,通常拿来获得别的进程的句柄,也可调用OpenProcess(GetCurrentProcessId)获得本进程真实句柄

  • 创建和结束进程
    BOOL CreateProcess(
    LPCTSTR lpApplicationName,应用程序全路径名
    LPTSTR lpCommandLine, // 命令行参数
    LPSECURITY_ATTRIBUTES lpProcessAttributes, // 安全属性 设为NULL
    LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程安全属性NULL
    BOOL bInheritHandles, // 继承标识 NULL
    DWORD dwCreationFlags, // 创建方式 给0立即启动
    LPVOID lpEnvironment, // 设置环境信息 可为NULL
    LPCTSTR lpCurrentDirectory, // 设置工作目录 可为NULL
    LPSTARTUPINFO lpStartupInfo, // 保存起始信息 需放入结构体地址
    LPPROCESS_INFORMATION lpProcessInformation // 创建的进程相关信息,需放入结构体地址
    );
    ExitProcess 可以结束当前进程
    TerminateProcess 可以结束别的进程
    CloseHandle 将句柄置为 -1,进程不结束

    • 进程间的等候,即阻塞函数等待别的进程返回
      DWORD WaitForSingleObject(
      HANDLE hHandle, // 进程句柄
      DWORD dwMilliseconds // 等待时间(INFINITE为无限长)
      );
      DWORD WaitForMultipleObjects(
      DWORD nCount, // 句柄数量
      CONST HANDLE *lpHandles, // 存放句柄的数组
      BOOL fWaitAll, // 等候方式TRUE等待所有 FALSE任何一个
      DWORD dwMilliseconds // 等待时间(INFINITE为无限长)
      );
      这两个等候的函数一个可以等待单个进程,一个可以等候多个,里头的HANDLE其实可以不光只是进程,也可以是线程,只要是带信号的句柄,这些句柄包括
      Change notification
      Console input 控制台输入
      Event 事件
      Job
      Mutex 互斥
      Process 进程
      Semaphore 信号
      Thread 线程
      Waitable timer 可等候定时器

线程

进程如果对应电脑的内存,线程对应着电脑的CPU,线程也就是执行的代码的实例。
系统是以线程为单位调度程序。
线程的调度: 将CPU的执行时间划分成时间片,依次根据时间片执行不同的线程。

- 创建
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, //安全属性
DWORD dwStackSize, // 线程栈大小为0向1M靠拢
LPTHREAD_START_ROUTINE lpStartAddress, // 线程处理函数
LPVOID lpParameter, // 处理函数参数
DWORD dwCreationFlags, //创建方式 挂起还是执行
LPDWORD lpThreadId // 接收的线程ID
);
- 结束 TerminateThread / ExitThread
结束后依旧需要调用CloseHandle释放句柄资源
- 挂起/执行 SuspendThread ResumeThread
- 线程信息 GetCurrentThreadId / GetCurrentThread

线程同步

线程同步技术是解决线程之间的资源竞争和线程之间的协调工作。
其中,原子锁、临界区(段)、互斥 是给线程间加锁,

  • 原子锁
    直接对一个数据的内存操作,任一时间只有一个线程访问该内存,可对这个数据进行增,减,改变数值
    InterlockedIncrement, InterlockedExchange, InterlockedDecrement
  • 临界区
    可以锁定一段代码,防止多个线程同时使用该段代码
    VOID InitializeCriticalSection(
    LPCRITICAL_SECTION lpCriticalSection // 临界区结构体的地址
    ); //初始化一个临界区
    VOID EnterCriticalSection(
    LPCRITICAL_SECTION lpCriticalSection
    ); //进入临界区,放在要锁定的代码前
    VOID LeaveCriticalSection(
    LPCRITICAL_SECTION lpCriticalSection //
    ); //离开临界区,放在锁定的代码结尾
    VOID DeleteCriticalSection(
    LPCRITICAL_SECTION lpCriticalSection
    ); //释放临界区资源

  • 互斥
    用于多线程下代码或资源的共享使用
    HANDLE CreateMutex(
    LPSECURITY_ATTRIBUTES lpMutexAttributes,
    // 安全属性
    BOOL bInitialOwner, // 初始拥有着,TRUE立刻获得互斥锁
    LPCTSTR lpName // 互斥名
    ); //返回互斥句柄
    一个进程调用WaitForSingleObject时,如果持锁,则无需等待,否则等待持锁线程调用ReleaseMutext时立刻获得互斥锁
    CloseHandle 可以释放互斥锁句柄资源,OpenMutex可以根据互斥名获得互斥锁句柄,也可以使用在两个进程间的通信。

    注: 互斥和临界区的区别,
    临界区 - 运行在用户态,执行效率高,只能在同一个进程中使用
    互斥 - 运行在内核态,执行效率低,可以通过命名方式跨进程使用(配合内存映射文件)

  • 事件
    事件用于程序之间的通知的问题,是最常用的线程同步技术,事件句柄也分为有信号和无信号两种状态,无信号时会被WaitFor..函数等待,而SetEvent和ResetEvent可以手动设置事件句柄的信号状态
    HANDLE CreateEvent(
    LPSECURITY_ATTRIBUTES lpEventAttributes,
    // 安全属性
    BOOL bManualReset, // 手动还是自动复位
    BOOL bInitialState, // 初始状态(有无信号)
    LPCTSTR lpName // 事件名字
    );
    另一进程调用WaitFor..函数等待时间句柄变为有信号状态,如果是自动复位,会在调用结束后信号立马变成无信号状态,如果是手动,需要在调用结束后使用ResetEvent将信号置为无信号状态
    不使用以后使用CloseHandle关闭事件句柄

  • 信号量
    类似于事件,解决通知的相关问题,可以提供一个计数器,设置信号有效的次数
    HANDLE CreateSemaphore(
    LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
    // 安全属性
    LONG lInitialCount, // 初始计数值
    LONG lMaximumCount, // 最大值
    LPCTSTR lpName // 信号量名字
    );
    当一个线程调用WaitFor..函数会使信号量计数值减1,直到该值为0这个信号量会变为无信号状态。使用ReleaseSemaphore可以重置信号量的计数值。使用结束后依旧使用CloseHandle释放资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值