每次处理并行任务时,如果要等待用户输入或依赖外部(如与灿亨控制器响应),就应该为类似的操作单独创建一个线程,这样我们的程序才不会挂起无响应。
静态库和动态库
静态库是指在程序运行前就编译完成的库,如#include行为;
动态库指在程序运行时进行链接的库,如user32.dll.

一、事件处理器和消息传递接口

该程序演示了一个只有关闭功能的窗口


#include <Windows.h> //处理一些视觉特效,例如窗口,控件,枚举,样式

//在创建一个应用程序之前,必须先声明一个窗口过程的原型才能在窗口结构中使用它
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

//WINAPI或stdcall意味着栈的清理工作由被调用函数来完成
//hThis是应用程序当前实例的句柄;hPrev是应用程序上一个实例的句柄;
//szCmdLine是应用程序的命令行,包括该程序的名称;iCmdShow控制如何显示窗口
int WINAPI WinMain(HINSTANCE hThis, HINSTANCE hPrev, LPSTR szCmdLine, int iCmdShow)
{
    UNREFERENCED_PARAMETER(hPrev); //告诉编译器不能使用某些参数,方便编译器进行一些额外的优化
    UNREFERENCED_PARAMETER(szCmdLine);

    WNDCLASSEX wndEx = { 0 }; //实例化窗口结构
    wndEx.cbClsExtra = 0; //实例化窗口类后分配的额外字节数
    wndEx.cbSize = sizeof(wndEx); //窗口结构的大小(字节为单位)
    wndEx.cbWndExtra = 0; //实例化窗口实例后分配的额外字节数
    wndEx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); //窗口类背景画刷的句柄
    wndEx.hCursor = LoadCursor(NULL, IDC_ARROW); //窗口类光标的句柄
    wndEx.hIcon = LoadIcon(NULL, IDI_APPLICATION); //窗口类图标的句柄
    wndEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION); //窗口类图标的句柄
    wndEx.hInstance = hThis; //窗口过程的实例句柄
    wndEx.lpfnWndProc = WndProc; //指向窗口过程的指针
    wndEx.lpszClassName = TEXT("GUIProject"); //指向以空字符结尾的字符串或原子的指针
    wndEx.lpszMenuName = NULL; //指向以空字符结尾的字符串的指针,该字符串指定了窗口类菜单的资源名
    wndEx.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClassEx(&wndEx))
    {
        return -1;
    }

    HWND hWnd = CreateWindow( wndEx.lpszClassName, TEXT("GUI Project"), WS_OVERLAPPEDWINDOW,
                              200, 200, 400, 300, HWND_DESKTOP, NULL, hThis, 0);
    if (!hWnd)
    {
        return -1;
    }

    UpdateWindow(hWnd);

    ShowWindow(hWnd, iCmdShow); //设置指定窗口的显示状态
    MSG msg = { 0 }; //显示窗口消息

    while (GetMessage(&msg, NULL, NULL, NULL))
    {
        TranslateMessage(&msg); //把虚拟键消息翻译成字符消息
        DispatchMessage(&msg); //分发一条消息给窗口过程
    }

    DestroyWindow(hWnd);
    UnregisterClass(wndEx.lpszClassName, hThis); //注销窗口类,释放该类占用的内存
    return (int)msg.wParam; //从应用程序消息队列中返回一个成功推出代码或最后一个消息代码
}

//hWnd表示窗口标识,uMsg窗口消息代码(无符号整数),wParam和lParam传递应用程序定义的数据(64位长整型数)
//函数返回64位有符号长整型
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CLOSE:
    {
        PostQuitMessage(0); //释放系统资源,并安全关闭该应用程序
        break;
    }
    default:
    {
        //处理应用程序未处理的窗口信息,函数确保每个消息都被处理
        return DefWindowProc(hWnd, uMsg, wParam, lParam); //默认窗口过程
    }
    }
    return 0;
}

出现如下错误:

严重性 代码  说明  项目  文件  行   禁止显示状态
警告  C28251  “WinMain”的批注不一致: 此实例包含 无批注。请参见 c:\program files (x86)\windows kits\10\include\10.0.18362.0\um\winbase.h(933)。   GUIProject  C:\USERS\CDQ\SOURCE\REPOS\GUIPROJECT\GUIPROJECT\MAIN.CPP    6   

原因是建立的是控制台项目而不是win32项目,解决方法:

配置属性-->链接器-->系统-->子系统-->窗口,之后点击确定。

参考自:https://bbs.csdn.net/topics/392512424?list=63174050

二、解释进程模型

传统操作系统必须提供创建进程和终止进程的方法,下面列出4个引发创建进程的主要事件:

  1. 系统初始化;
  2. 正在运行的进程执行创建进程的系统调用;
  3. 用户要求创建新进程;
  4. 启动批处理工作。

创建一个打开Windows笔记本的进程:

#include <iostream>
#include<windows.h>
int main()
{
    std::cout << "Hello World!\n";

    STARTUPINFO startupinfo = { 0 };
    PROCESS_INFORMATION processInfomation = {0};
        //CreateProcess函数用于创建一个新进程和其主线程。
    BOOL bSucess = CreateProcess(TEXT("C:\\windows\\notepad.exe"), NULL, NULL, NULL, FALSE, NULL, NULL, NULL, &startupinfo, &processInfomation);
    if (bSucess)
    {
        std::cout << "Process started." << std::endl
            << "Process ID:\t" << processInfomation.dwProcessId << std::endl;
    }
    else
    {
        std::cout << "Cannont create process!" << std::endl
            << "Error code:\t" << GetLastError() << std::endl;
    }
    return system("pause");
}

终止进程的较好办法是调用ExtiProcess函数。

三、进程状态

运行:该进程正在使用CPU;
就绪:该进程可运行,但是没有CPU可用,还在排队等待其他进程放弃CPU的使用权;
阻塞:在某些外部事件发生前,该进程不能运行。


#include <iostream>
#include<windows.h>
//winternl包含了Windows内部函数大部分原型和数据类型
#include<winternl.h>

using std::cout;
using std::endl;

typedef NTSTATUS(WINAPI* QUERYINFORMATIONPROCESS)(
    HANDLE processHandle,
    PROCESSINFOCLASS processInformationClass,
    PVOID processInformation,
    ULONG processInformationLength,
    PULONG returnLength);

int main()
{
    std::cout << "Hello World!\n";

    STARTUPINFO startupinfo = { 0 };
    PROCESS_INFORMATION processInfomation = { 0 };

    BOOL bSuccess = CreateProcess(TEXT("C:\\windows\\notepad.exe"), NULL, NULL, NULL,
        FALSE, NULL, NULL, NULL, &startupinfo, &processInfomation);
    if (bSuccess)
    {
        std::cout << "Process started." << std::endl
            << "Process ID:\t" << processInfomation.dwProcessId << std::endl;

        PROCESS_BASIC_INFORMATION pbi;
        ULONG ulength = 0;

        HMODULE hDll = LoadLibrary(TEXT("C:\\windows\\System32\\ntdll.dll"));

        if (hDll)
        {
            QUERYINFORMATIONPROCESS QueryInformationProcess = (QUERYINFORMATIONPROCESS)GetProcAddress(hDll, "NtQueryInformationProcess");
            if (QueryInformationProcess)
            {
                NTSTATUS ntStatus = QueryInformationProcess(processInfomation.hProcess, PROCESSINFOCLASS::ProcessBasicInformation, &pbi, sizeof(pbi), &ulength);
                if (NT_SUCCESS(ntStatus))
                {
                    cout << "Process ID (from PCB):\t" << pbi.UniqueProcessId << endl;
                }
                else
                {
                    cout << "Cannot open PCB!" << endl
                        << "Error code:\t" << GetLastError() << endl;
                }
            }
            else
            {
                cout << "Cannot get NTQueryInformationProcess function!" << endl
                    << "Error code:\t" << GetLastError() << endl;
            }
            FreeLibrary(hDll);
        }
        else
        {
            cout << "Cannnot load ntdll.dll" << endl
                << "Error code:\t" << GetLastError() << endl;
        }
    }
    else
    {
        std::cout << "Cannont create process!" << std::endl
            << "Error code:\t" << GetLastError() << std::endl;
    }
    //CloseHandle(processInfomation.hProcess);
    //CloseHandle(processInfomation.hThread);
    return 0;
}
Hello World!
Process started.
Process ID:     11492
Process ID (from PCB):  11492

Windows多线程编程入门笔记的更多相关文章

  1. Windows多线程编程入门

    标签(空格分隔): Windows multithread programming 多线程 并发 编程 背景知识 在开始学习多线程编程之前,先来学习下进程和线程 进程 进程是指具有一定独立功能的程序在 ...

  2. 多线程编程学习笔记——async和await(三)

    接上文 多线程编程学习笔记——async和await(一) 接上文 多线程编程学习笔记——async和await(二) 五.   处理异步操作中的异常 本示例学习如何在异步函数中处理异常,学习如何对多 ...

  3. 多线程编程学习笔记——使用异步IO(一)

    接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...

  4. 多线程编程学习笔记——使用异步IO

    接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...

  5. C++Windows核心编程读书笔记

    转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...

  6. windows多线程编程星球(一)

    以前在学校的时候,多线程这一部分是属于那种充满好奇但是又感觉很难掌握的部分.原因嘛我觉得是这玩意儿和编程语言无关,主要和操作系统的有关,所以这部分内容主要出现在讲原理的操作系统书的某一章,看完原理是懂 ...

  7. 转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)

    Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)   介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可 ...

  8. 多线程编程学习笔记——async和await(一)

    接上文 多线程编程学习笔记——任务并行库(一) 接上文 多线程编程学习笔记——任务并行库(二) 接上文 多线程编程学习笔记——任务并行库(三) 接上文 多线程编程学习笔记——任务并行库(四) 通过前面 ...

  9. 多线程编程学习笔记——async和await(二)

    接上文 多线程编程学习笔记——async和await(一) 三.   对连续的异步任务使用await操作符 本示例学习如何阅读有多个await方法方法时,程序的实际流程是怎么样的,理解await的异步 ...

随机推荐

  1. Anaconda 下 Jupyter 更改默认启动路径和默认浏览器

    1.Jupyter 更改默认启动路径方法 输入jupyter notebook --generate-config 会生成jupyter_notebook_config.py 找到文件,并打开 将 # ...

  2. Python3-def

    def hello(): print("这是一个无参数的方法!") hello(); print("") def helloOne(str): print(st ...

  3. spring的finishBeanFactoryInitialization方法分析

    spring源码版本5.0.5 概述 该方法会实例化所有剩余的非懒加载单例 bean.除了一些内部的 bean.实现了 BeanFactoryPostProcessor 接口的 bean.实现了 Be ...

  4. Luogu P2602 [ZJOI2010]数字计数 数位DP

    很久以前就...但是一直咕咕咕 思路:数位$DP$ 提交:1次 题解:见代码 #include<cstdio> #include<iostream> #include<c ...

  5. xml------文件打开样式

    -----添加css样式修饰 引入css样式 浏览器展示 -------- 在服务器上通过 XSLT 转换 XML xsl文件 样式展示

  6. js 获取当前focus 的 input 元素

    document.querySelector("#pro-code").focus(); console.log("focus:" + document.act ...

  7. 【原创】洛谷 LUOGU P3366 【模板】最小生成树

    P3366 [模板]最小生成树 题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz 输入输出格式 输入格式: 第一行包含两个整数N.M,表示该图共有N个结点和M条无向边.(N ...

  8. xgboost 特征重要性计算

    在XGBoost中提供了三种特征重要性的计算方法: ‘weight’ - the number of times a feature is used to split the data across ...

  9. 我的zshrc文件设置备份

    # If you come from bash you might have to change your $PATH. # export PATH=$HOME/bin:/usr/local/bin: ...

  10. C# 7 .NET / CLR / Visual Studio version requirements

    C# 7 .NET / CLR / Visual Studio version requirements   You do NOT need to target .NET 4.6 and above, ...