Windows进程与线程

进程的组成

进程是惰性的
进程要做任何事情, 都必须让线程来运行
线程执行进程地址空间中包含的代码
一个进程可以拥有多个线程
所有的线程都能在进程的地址空间中"同时"运行代码
每个线程都有它自己的一组CPU寄存器和自己的堆栈
每个进程必须有一个线程
当系统创建一个进程时, 会自动创建第一个线程, 这个线程我们称为主线程
如果没有线程要执行进程地址空间中的代码, 进程就失去了存在的意义
此时系统会自动销毁进程以及它的地址空间
操作系统会以轮询的方式为每个线程分配CPU时间片, 从而营造出并行的假象
如果计算机拥有多个CPU, 操作系统会以更复杂的方式为线程分配CPU时间片.

内核对象

操作系统用来管理进程

地址空间

包含了可执行文件及DLL模块的代码和数据

控制台用户界面

控制台程序是基于文本的
它一般不会创建窗口或进程消息, 而且不需要GUI
我们称之为CUI

图形用户界面

GUI程序是一个图形化的前端
它可以创建窗口, 拥有菜单
可以通过对话框与用户交互
可以使用所以标准的"视窗化"的东西
Windows上绝大部分的附加应用程序都是GUI的

区别

在VS中, CUI程序的链接器开关为/SUBSYSTEM:CONSOLE, GUI程序的链接器开关为/SUBSYSTEM:WINDOWS
在加载时, 会获取这个值
如果是一个文本控制台窗口, 操作系统会使用命令提示符启动这个程序
否则, 操作系统加载这个程序后, 由应用程序来管理自己的窗口

GUI的入口函数是 WinMain
CUI的入口函数是 main
GUI的启动函数为 WinMainCRTStartup 或 wWinMainCRTStartup
CUI的启动函数为 mainCRTStartup 或 wmainCRTStartup

进程实例句柄

通过GetModuleHandle获取
HMODULE WINAPI GetModuleHandle
(
  _In_opt_  LPCTSTR lpModuleName
);
获取自身句柄时传参为nullptr
通过这个函数获取的hInstance就是程序的基地址
在VS2015中, 默认是随机基址
如果关闭随机基址, 默认基址是0x400000

命令行参数

#include <stdio.h>
#include <Windows.h>

int main()
{
    TCHAR* const strCommandLine = GetCommandLine();
    // 通过这个函数获取到的命令行尽量不要去修改,否则会影响全局的内容.也不要手动去释放这块空间
    它应该是跟着程序一起消亡的
    int nArgc;

    TCHAR** ppArgv = CommandLineToArgvW(szCommandLine, &nArgc);
    //通过该函数对命令行分割,方便使用,一般从1开始,0为程序当前路径
    if (ppArgv)
    {
        for (int i = 1; i < nArgc; ++i)
        {
            _tprintf(TEXT("%s\n"), ppArgv[i]);
        }
    }
    LocalFree(ppArgv);  

    return 0;
}

环境变量

    LPTCH strPath = GetEnvironmentStrings();
    while (*strPath)
    {
        _tprintf(TEXT("%s\n"), strPath);
        strPath += lstrlen(m_strPath) + 1;
    }
    FreeEnvironmentStrings(m_strPath);
    // strPath是一个以\0分割的字符串,结尾是\0\0,通过上面的方式打印出环境变量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值