Windows 进程及线程
进程的组成
- 进程是
惰性的 - 进程要做任何事情, 都必须让
线程来运行 - 线程执行进程地址空间中包含的代码
一个进程可以拥有
多个线程- 所有的
线程都能在进程的地址空间中"同时"运行代码 每个线程都有它自己的一组CPU寄存器和自己的堆栈
- 所有的
每个进程
必须有一个线程- 当系统创建一个进程时, 会自动创建第一个线程, 这个线程我们称为
主线程 - 如果没有线程要执行进程地址空间中的代码, 进程就失去了存在的意义
- 此时系统会自动销毁进程以及它的地址空间
- 当系统创建一个进程时, 会自动创建第一个线程, 这个线程我们称为
- 操作系统会以轮询的方式为每个线程分配CPU时间片, 从而营造出
并行的假象 - 如果计算机永远多个CPU, 操作系统会以更复杂的方式为线程分配CPU时间片.
内核对象
操作系统用来管理进程的
地址空间
包含了可执行文件及DLL模块的代码和数据
应用程序类型
控制台用户界面
- 控制台程序是基于文本的
- 它一般不会创建窗口或进程消息, 而且不需要GUI
- 我们称之为CUI
图形用户界面
- GUI程序是一个图形化的前端
- 它可以创建窗口, 拥有菜单
- 可以通过对话框与用户交互
- 可以使用所以标准的"视窗化"的东西
- Windows上绝大部分的附加应用程序都是GUI的
区别
在VS中, CUI程序的链接器开关为
/SUBSYSTEM:CONSOLE, GUI程序的链接器开关为/SUBSYSTEM:WINDOWS- 在加载时, 会获取这个值
- 如果是一个文本控制台窗口, 操作系统会使用
命令提示符启动这个程序 - 否则, 操作系统加载这个程序后, 由应用程序来管理自己的窗口
入口函数不同
- GUI的入口函数是 _tWinMain
INT WINAPI _tWinMain(
HINSTANCE hInstanceExe,
HINSTANCE hPreInstance,
PTSTR pszCmdLine,
INT nCmdShow);- CUI的入口函数是 _tmain
INT _tmain(
INT argc,
TCHAR* argv[],
TCHAR* envp[]);启动函数不同
- GUI的启动函数为
WinMainCRTStartup或wWinMainCRTStartup - CUI的启动函数为
mainCRTStartup或wmainCRTStartup
- GUI的启动函数为
进程实例句柄
加载到进程地址空间的每一个执行体或者DLL文件, 都被赋予了一个独一无二的实例句柄
#include <stdio.h>
#include <Windows.h>
int main()
{
HINSTANCE hInstance = GetModuleHandle(NULL);
printf("0x%x\n", hInstance);
return 0;
}- 此时, 这个hInstance就是我们程序的
基地址 - 在VS2015中, 默认是
随机基址 - 如果不进行
随机基址, 默认基址是0x400000
HMODULE和HINSTANCE是一摸一样的的东西, 没有任何区别
进程的命令行参数
#include <stdio.h>
#include <Windows.h>
int main()
{
TCHAR* /*const*/ szCommandLine = GetCommandLine();
// 需要注意的是, szCommandLine 尽量不要修改, 会影响全局的内容
// 也不要尝试去手动释放这一块空间
int nArgc;
TCHAR** ppArgv = CommandLineToArgvW(szCommandLine, &nArgc);
if (ppArgv)
{
for (int i = 0; i < nArgc; ++i)
{
_tprintf(TEXT("%s\n"), ppArgv[i]);
}
}
LocalFree(ppArgv); // 释放
return 0;
}进程的环境变量
#include <stdio.h>
#include <Windows.h>
int main()
{
// 获取环境变量
LPTCH szPath = GetEnvironmentStrings();
_tprintf(TEXT("%s\n"), szPath);
// 释放资源
FreeEnvironmentStrings(szPath);
return 0;
}这里需要注意的是:
- szPath是一个以
\0分割的字符串 - 结尾是
\0\0 - 需要自己写函数来进行分割字符串
环境变量的其他函数:
GetEnvironmentVariable
获取某个环境变量的值
DWORD WINAPI GetEnvironmentVariable(
_In_opt_ LPCTSTR lpName, // 要获取的环境变量的名称
_Out_opt_ LPTSTR lpBuffer, // 要存放值的内存地址
_In_ DWORD nSize // buff的大小
);SetEnvironmentVariable
设置某个环境变量的值
注意, 调用此方法后, 并不影响系统本身的设置, 也不影响其他应用程序的环境变量, 仅对当前应用程序生效
BOOL WINAPI SetEnvironmentVariable(
_In_ LPCTSTR lpName, // 环境变量的名称
_In_opt_ LPCTSTR lpValue // 环境变量的值
);未完待续...
如有错误,请提出指正!谢谢.
本文由 花心胡萝卜 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: 2017-06-05 at 01:53 am