淄博做企业网站哪家好,百度联盟怎么做自己的网站,家居定制公司股票,云筑网第三章 进程 发现这本书的文字很简练#xff0c;知识点突出#xff0c;而且翻译的基本没有拗口的地方#xff0c;是本好书#xff0c;(^o^)/~
下面进入正题。
关于内存映射
Windows内存管理的分页机制在微机原理课程中有提到#xff0c;后面的章节也有相关内容。这里提… 第三章 进程 发现这本书的文字很简练知识点突出而且翻译的基本没有拗口的地方是本好书(^o^)/~
下面进入正题。
关于内存映射
Windows内存管理的分页机制在微机原理课程中有提到后面的章节也有相关内容。这里提前写是怕以后忘了写出来。 一直不明白”内存映射“是怎么一回事如很多编程资料中都会说DLL在内存中只有一份只是映射到不同进程的地址空间中但是具体怎么映射的让人只知其一不知其二。还有后面的内存映射文件到底是怎么映射的使用分页机制可以解释。所谓分页机制就是使用高速缓冲区制作一个表先将线性地址分解成各个部分然后分级查找到此线性地址所对应的内存页面通常4KB。而这个表的内容是由操作系统来管理的。那么要实现共享DLL所在内存或者其他内存只需要把相应的页面地址填入进程对应的高速缓冲区中即可这是基本原理其中不是页面对其的内存是怎么处理的这些细节问题只有通过继续学习才能知道虽然说对于编写程序没什么影响但是作为一名C/C程序员尽可能多地了解更多的底层知识总不是件坏事。
知识点汇总
Win32的进程是惰性的。每个进程必须拥有一个主线程primary thread才能工作。换句话说Windows在创建一个进程时同时会为此进程创建一个线程。这种处理方式把进程和线程完全分开了能运行的只有线程进程是线程的更大一级单位或者说是载体。在Linux中创建的进程是可以直接运行的相当于主线程这种处理方式将进程和线程区分得不是非常清楚。WinMain函数不是GUI程序的入口点它是由C运行时启动函数调用的。这么说又涉及到什么是运行时启动函数的问题。下面是我的理解C语言编程中的main()函数大家都知道吧这个就是入口函数。不管是运行CUI还是GUI程序都是先进入main()函数。如果是GUI程序main()函数会先做一些处理初始化一些变量然后调用WinMain函数。了解WinMain的几个参数。 hInstance进程的实例句柄hInstance是一个地址指向应用程序加载到内存时的起始地址在此程序的线性地址空间。它和hModule是一样的之所以存在两个称呼是由于历史原因在16位windows中遗留下来的称呼或者说为了保持兼容性而保留的。在测试时发现每次运行程序时这个值都会不一样。 相关函数32位windows下 GetModuleHandle(LPCTSTR lpszModule)获取已加载的EXE或DLL文件的起始地址。参数是模块名称注意查找范围仅限于当前进程。如果为NULL则返回此程序EXE在内存中的起始地址。另外如果在DLL中调用此函数同时参数为NULL返回的仍然是调用进程的地址而不是DLL的基地址和上面的结论相同。 hPrevInstance在16位的windows下表示此应用程序的前一个运行实例在32位下没有此意义只是为了兼容。 lpszCmdLine启动参数。非常特别需要注意的是它总一个ANSI字符串。当你CreateProcess时传入的非空命令行参数也必须为ANSI字符串否则应用程序会出错或者崩溃。 这个lpszCmdLine和CUI的main函数的命令行参数不一样第一个参数可执行文件路径被main除去之后传入了WinMain。 相关函数32bit LPTSTR GetCommandLine(VOID)获取命令行指针有ANSI版和UINCODE版。LPWSTR CommandLineToArgvW(LPWSTR cmdLine, LPINT pArgc)将宽字符版的命令行参数转换成参数数组数组个数保存在*pArgc中。 还可以使用全局变量来访问命令行参数_argv原始的ANSI字符串数组_argc。不过如果WinMain是在mian()函数中调用的那么自然可以访问mian()函数的两个参数argc, argv。 进程的环境变量。它就是一组全局字符串由系统设置这个字符串在注册表中可以找到。子进程继承自父进程但是进程间环境变量内存区是独立的。 相关函数 GetEnvironmentVariable()SetEnvironmentVaribale() 进程的驱动器目录可以通过环境变量来读写。 相关函数 SetCurrentDirectory() GetFullPathName() 操作系统个版本。 相关函数 DWORD GetVersionEx(LPOSVERSIONINFO lpVersionInformation) 重要函数CreateProcess() 上一段代码
// CreateProcess.cpp : 定义控制台应用程序的入口点。#include stdafx.h
#include windows.h
int _tmain(int argc, _TCHAR* argv[])
{//wprintf(L%s\n, (const wchar_t*)argv[0]);STARTUPINFOA si; // 这个结构体有些成员挺有用还有专门针对开发屏幕保护程序的标志另外WinMian()函数的nCmdShow也是通过此结构体传递的ZeroMemory(si, sizeof(si));si.cb sizeof(si);SECURITY_ATTRIBUTES saProcess;SECURITY_ATTRIBUTES saThread;saProcess.nLength sizeof(saProcess);saProcess.lpSecurityDescriptor NULL;saProcess.bInheritHandle TRUE; // 这是设置某个内核对象的可继承性saThread.nLength sizeof(saThread);saThread.lpSecurityDescriptor NULL;saThread.bInheritHandle FALSE; // 含义同saProcessPROCESS_INFORMATION piProcess;BOOL res CreateProcessA(NULL, // 如果非空则只在当前目录下查找notepad.exe, // 必须为ANSI字符串saProcess,saThread,false, // 这是针对进程这个特殊的内核对象独有的因为创建进程时需要创建内核句柄表这就存在是否继承父进程的问题。0,NULL, // 指向新的环境变量字符串区为NULL则使用默认的、继承自父进程的环境变量NULL, // 设置当前驱动器和工作路径必须包含盘符。为NULL则使用和父进程相同的驱动器和工作路径。si,piProcess // 只有它是输出不能NULL否则创建错误错误码为87参数错误);if (FALSE res){printf(创建新进程出错错误码%d, GetLastError());}return 0;
}结束进程 三种方法 主动调用ExitProcess()函数。外部调用TerminateProcess()函数不推荐使用会导致资源不能被释放以及DLL推出时执行的操作没有被执行等问题。进程中所有线程都结束系统会自动终止进程。特别的如果主线程是自然返回的话系统会调用ExitProcess()自动结束进程此时可能还有线程正在执行它们都将被终止。如果在主线程结束时想保持其他线程继续运行那么需要主线程主动调用ExitThread()终止自己。 进程结束不影响子进程。 使用WaitForSingleObject()实现阻塞调用进程直到子进程运行结束。 创建完全分离的子进程的要点是释放所有本进程中与子进程相关的句柄。
查看进程退出代码或者查看进程是否终结GetExitCodeProcess()。