win32第十六天

一、进程
1.基本概念
1)进程是一个容器,包含程序执行所需要的代码、数据、资源等信息。Windows是多任务操作系统,可以同时执行多个进程。
2)进程的特点
A.每个进程都有自己唯一的标识号——PID。
B.每个进程都有自己的安全属性。
C.每个进程都有自己的地址空间,进程之间不能互相访问的地址空间。
D.每个进程至少包含一个线程。
2.进程环境(进程上下文)
1)获取环境块
LPTCH GetEnvironmentStrings (void)
Name1=Value1\0Name2=Value2\0...NameN=ValueN\0\0
成功返回进程环境块指针,失败返回NULL。
2)释放环境块
BOOL FreeEnvironmentStrings (
  LPTCH lpszEnvironmentBlock // 进程环境块指针
);
成功返回TRUE,失败返回FALSE。
3)设置环境变量
BOOL SetEnvironmentVariable (
  LPCTSTR lpName, // 变量名
  LPCTSTR lpValue, // 变量值
);
成功返回TRUE,失败返回FALSE。
4)获取环境变量
DWORD GetEnvironmentVariable (
  LPCTSTR lpName, // 变量名
  LPTSTR   lpBuffer, // 变量值缓冲区
  DWORD nSize      // 变量值缓冲区大小(以字符为单位,含结尾空字符)
);
成功返回实际变量值字符串长度,失败返回0。
3.进程信息
1)获取进程ID
DWORD GetCurrentProcessId (void);
返回调用进程的ID。
2)获取进程句柄
HANDLE GetCurrentProccess (void);
返回调用进程的伪句柄,用于后续函数调用。
4.创建进程
1)WinExec - Win16遗留,现在基本不用
2)ShellExecute - Shell操作,速度慢
3)CreateProcess - 使用最多
BOOL CreateProcess (
  LPCTSTR lpApplicationName, // 可执行程序路径
  LPTSTR   lpComandLine,         // 命令行参数
  ...                                            // 进程安全属性,NULL
  ...                                            // 线程安全属性,NULL
  BOOL     bInheritHandles,       // 子进程是否可以继承父进程的句柄
  DWORD dwCreationFlags,      // 创建方式,0表示立即启动
  LPVOID  lpEnvironment,         // 子进程环境,NULL表示继承父进程环境
  LPCTSTR lpCurrentDirectory,  // 子进程工作目录,NULL表示继承父进程
                                                // 工作目录
  LPSTARTUPINFO lpStartupInfo, // 启动信息
  LPPROCESS_INFORMATION lpProcessInformation // 进程信息(输出)
);
typedef struct _PROCESS_INFORMATION {
  HANDLE hProcess; // 子进程句柄
  HANDLE hThread;  // 子进程的主线程句柄
  DWORD dwProcessId; // 子进程ID
  DWORD dwThreadId; // 子进程的主线程ID
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;
成功返回TRUE,失败返回FALSE。
5.等候进程
DWORD WaitForSingleObject (
  HANDLE hHandle,           // 句柄
  DWORD dwMilliseconds // 等候时间(毫秒),INFINITE永远等候
);
成功返回引起该函数返回的事件码,失败返回WAIT_FAILED(-1)
引起该函数返回的事件码:
WAIT_OBJECT_0 - 句柄有信号
WAIT_TIMEOUT - 超时
6.退出进程
VOID ExitProcess (
  UINT uExitCode // 退出码
);
7.终止进程
BOOL TerminateProcess (
  HANDLE hProcess,  // 进程句柄
  UINT      uExitCode // 退出码
);
成功返回TRUE,失败返回FALSE。
8.通过进程ID获取句柄
HANDLE OpenProcess (
  DWORD dwDesireAccess, // 访问权限,PROCESS_ALL_ACCESS
  BOOL     bInheritHandle,  // 子进程是否继承此函数所返回的句柄
  DWORD dwProcessId       // 进程ID
);
成功返回对应给定进程ID的进程句柄,失败返回NULL。
二、线程
1.基本概念
1)线程是可以执行的代码实例。系统以线程为单位调度程序。一个程序可以包含多个线程,实现多任务。
2)线程的特点
A.每个线程都有自己的唯一标识——TID。
B.每个线程都有自己的安全属性。
C.每个线程都有自己的内存堆栈。
void foo (void) {
  static int a = 10;
  a++;
}
D.每个线程都有自己的寄存器信息。
c = a + b;
3)进程多任务和线程多任务
A.系统中的多个进程地址空间独立,彼此交换数据困难。
B.一个进程中的多个线程地址空间共享,彼此交换数据方便,容易产生冲突。
4)线程调度:将CPU的执行时间划分成若干时间片,分配给不同的线程。操作系统根据时间片的分配,轮流执行不同的线程。
2.线程过程函数
DWORD WINAPI ThreadProc (
  LPVOID lpParameter // 线程参数
);
返回值代表线程执行的成功或失败,可由GetExitCodeThread函数获得。
3.创建线程
HANDLE CreateThread (
  ...                              // 安全属性,NULL
  SIZE_T dwStackSize, // 线程栈的初始字节数,0表示与调用线程相同
  LPTHREAD_START_ROUTINE lpStartAddress, // 线程过程函数地址
  LPVOID lpParameter, // 线程参数
  DWORD dwCreationFlags, // 创建方式
  LPDWORD lpThreadId // 线程ID(输出)
);
成功返回线程句柄,失败返回NULL。
dwCreationFlags取值:
0 - 立即运行
CREATE_SUSPENDED - 创建后先挂起,直到调用ResumeThread函数再运行
4.退出线程
VOID ExitThread (
  DWORD dwExitCode // 退出码
);
5.终止线程
BOOL TerminateThread (
  HANDLE hThread,      // 线程句柄
  DWORD dwExitCode // 退出码
);
成功返回TRUE,失败返回FALSE。
6.挂起线程
DWORD SuspendThread (
  HANDLE hThread  // 线程句柄
);
成功返回线程此前被挂起的次数,失败返回-1。
7.恢复线程
DWORD ResumeThread (
  HANDLE hThread  // 线程句柄
);
成功返回线程此前被恢复的次数,失败返回-1。
8.获取线程ID
DWORD GetCurrentThreadId (VOID);
返回调用线程的ID。
9.获取线程句柄
HANDLE GetCurrentThread (VOID);
返回调用线程的句柄。
10.通过线程ID获取句柄
HANDLE OpenThread (
  DWORD dwDesireAccess, // 访问权限,THREAD_ALL_ACCESS
  BOOL     bInheritHandle,  // 子进程是否继承此函数所返回的句柄
  DWORD dwThreadId       // 线程ID
);
成功返回对应给定线程ID的线程句柄,失败返回NULL。
11.关闭线程句柄
CloseHandle (hThread);
三、线程同步
1.原子锁(Interlocked)
S1: g_cn -> 寄存器
S2: 寄存器的值+1
S3: 寄存器 -> g_cn
g_cn 0
I
0 -> 寄存器    - 寄存器里值0
寄存器的值+1 - 寄存器里值1 -> 备份
II
0 -> 寄存器    - 寄存器里值0
寄存器的值+1 - 寄存器里值1
1 -> g_cn      - g_cn 1
++
++
++
++
g_cn 5
I
1 -> g_cn      - g_cn 1
1)原子自增
LONG InterlockedIncrement (
  LPLONG lpAddress // 自增变量地址
);
返回自增以后的结果。
2)原子自减
LONG InterlockedDecrement (
  LPLONG lpAddress // 自减变量地址
);
返回自减以后的结果。
2.临界区(Critical Section)
CRITICAL_SECTION - 临界区结构体
1)初始临界区
VOID InitializeCriticalSection (
  LPCRITICAL_SECTION lpCriticalSection // 临界区结构体地址
);
2)进入临界区
VOID EnterScriticalSection (
  LPCRITICAL_SECTION lpCriticalSection // 临界区结构体地址
);
阻塞,直到调用线程获得对指定临界区对象的所有权才返回。任何时候只有一个线程拥有临界区对象的所有权。
3)离开临界区
VOID LeaveCriticalSection (
  LPCRITICAL_SECTION lpCriticalSection // 临界区结构体地址
);
4)删除临界区
VOID DeleteCriticalSection (
  LPCRITICAL_SECTION lpCriticalSection // 临界区结构体地址
);
3.互斥体(Mutex)
1)创建互斥体
HANDLE CreateMutex (
  ...                                    // 安全属性,NULL
  BOOL      bInitialOwner, // 调用线程是否初始拥有该互斥体
  LPCTSTR lpMame           // 互斥体名字
);
成功返回互斥体句柄,失败返回NULL。
2)等待互斥体
WaitForSingleObject (hMutex, INFINITE);
若其它线程拥有该互斥体,则hMutex无信号,函数阻塞,直到调用线程获得对该互斥体的所有权,此时hMutex有信号,函数返回。
3)释放互斥体
BOOL ReleaseMutex (
  HANDLE hMutex // 互斥体句柄
);
成功返回TRUE, 失败返回FALSE。
4)关闭互斥体
CloseHandle (hMutex);
4.信号量(Semaphore)
1)创建信号量
HANDLE CreateSemaphore (
  ...                                       // 安全属性,NULL
  LONG     lInitialCount,        // 初始资源计数
  LONG     lMaximumCount, // 最大资源计数
  LPCTSTR lpName               // 信号量名称
);
成功返回信号量句柄,失败返回NULL。
2)等待信号量
WaitForSingleObject (hSemaphore, INFINITE);
若资源计数为0,则hSemaphore无信号,函数阻塞,直到资源计数大于0,此时hSemaphore有信号,函数返回,同时资源计数减1。
3)释放信号量
BOOL ReleaseSemaphore (
  HANDLE hSemaphore,    // 信号量句柄
  LONG     lReleaseCount, // 资源计数增量
  LPLONG lpPreviousCount // 此前资源计数,可为NULL
);
成功返回TRUE,失败返回FALSE。4)关闭信号量
Cl
oseHandle (hSemaphore);
5.线程局部存储
局部与线程的全局变量。
1)分配线程局部存储
DWORD TlsAlloc (VOID);
成功返回线程局部存储索引,失败返回-1。
2)保存数据到线程局部存储
BOOL TlsSetValue (
  DWORD dwTlsIndex, // 线程局部存储索引
  LPVOID  lpTlsValue   // 数据
);
成功返回TRUE,失败返回FALSE。
3)从线程局部存储中获取数据
LPVOID TlsGetValue (
  DWORD dwTlsIndex // 线程局部存储索引
);
成功返回线程局部存储中的数据,失败返回NULL。
4)释放线程局部存储
BOOL TlsFree (
  DWORD dwTlsIndex // 线程局部存储索引
);
成功返回TRUE,失败返回FALSE。
5)静态线程局部存储
__declspec (thread) int g_cn = 0;
__declspec (thread) static int s_cn = 0;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值