14、Windows API 进程、线程、模块-阿里云开发者社区

开发者社区> hopegrace> 正文

14、Windows API 进程、线程、模块

简介: 一、基本概念  1、进程是应用程序的实例。进程包括一个虚拟地址空间及代码、数据、对象等程序运行所需环境和资源的集合。在内存空间中包括若干可执行的代码、数据、资源、一系列对系统对象操作的句柄,安全上下文、进程标识符(PID),环境变量等程序执行的环境。
+关注继续查看

一、基本概念 

1、进程是应用程序的实例。进程包括一个虚拟地址空间及代码、数据、对象等程序运行所需环境和资源的集合。在内存空间中包括若干可执行的代码、数据、资源、一系列对系统对象操作的句柄,安全上下文、进程标识符(PID),环境变量等程序执行的环境。同时,进程还包括一个或多个执行线程。 

        线程是程序的执行流程在操作系统层面,线程是需要操作系统为其分配执行时间片的基本单元。线程附属于进程,一个线程可以执行进程中任意部分的代码。一个系统中同一时间只能有少量线程执行(决定于CPU个数和核数),操作系统决定当前执行哪一个线程,并进行调度。每一个线程都包括一个上下文(主要是CPU寄存器值)。在进行线程调度时,系统会保存线程上下文。

        一个程序由多个模块组成。程序没有运行时,模块以可执行文件的形式存在(exe、dll等);程序运行后,所需要的模块都加载到进程的虚拟地址空间中,进行初始化的设置后,各模块就可以协同工作。每一个模块都可能包括代码、数据、资源等。

2、可执行文件

        程序的载体是可执行文件。可执行文件中包括运行所需的程序、数据及一些配置信息等。Windows平台的可执行文件包括exe、dll、sys等扩展名的文件。

        Windows平台的可执行文件基本都是PE格式的。

3、应用程序

应用程序是由一系列具有特定功能、能完成执行操作的可执行文件、数据的集合,一个应用程序可以包括若干个可执行程序、动态链接库、数据文件。Windows平台的应用程序根据与用户交互的方式区分为控制台应用程序与图形用户界面( GUI)程序;编译程序时通过/SUBSYSTE选择。

4、进程

        进程提供了程序运行所需要的资源、虚拟内存地址空间、各种数据、可执行的代码、需要使用到的各种内核对象、系统调用接口、优先级与权限配置、工作集、环境变量等,还包括至少一个执行过程(线程)。

进程是正在运行的程序,即程序的运行实例。

        每个进程都有一个标识符(PID)和一个句柄,系统和其他进程可以通过PID和进程的句柄对进程进行管理和操作。

5、动态链接库

        动态链接库是将应用程序模块化的重要方法

程序是在进程创建或程序运行时进行链接的,因此称为“动态链接”静态链接是在程序构建时由链接器进行链接,将代码和数据组织在同一个可执行文件中

6、模块

        每个可执行程序都可以称作一个模块,DLL文件是模块。exe文件也是模块,称为主模块。

7、线程

        进程的这种同时处理多个任务的能力是通过线程机制实现的。

        线程是附属在进程上的执行实体,是代码的执行流程。

       一个进程中可以有多个线程在并发执行。进程的所有线程都共享其虚拟地址空间、数据、系统资源等。每个线程都有自己的栈、上下文(context,包括CPU寄存器值等,线程调度时会进行线程上下文切换)、异常处理程序、调度优先级、标识符等。线程的切换依赖于中断。

        每个进程必须有至少一个线程,在进程创建时即开始执行的线程是进程的主线程,主线程可以再创建其他线程。

8、纤程( Fiber)

       纤程也是程序执行单元,与线程类似。不同的是纤程必须要应用程序自行调度,而线程是由系统进行调度的。纤程运行于线程的上下文中,一个线程可以调度很多纤程。

9、作业(Job,也称为工作项)

       作业是一种对象,可以将一组进程作为一个单元进行管理。作业包括命名对象(namable)安全对象(securable)和共享对象(sharable),可以控制进程组的属性。

二、进程相关API

Process and Thread Functions

http://msdn.microsoft.com/en-us/library/ms684847%28VS.85%29.aspx

    如果进程知道其他进程的标识符( PID),还可以通过OpenProcess函数获取进程的句柄,也可以通过GetProcessId通过句柄获取PID。

创建进程示例

创建进程示例

**************************************/
/* 头文件 */
#include
<windows.h>
#include
<stdio.h>

DWORD CreateChildProcess(LPSTR szChildProcessCmd);

/*************************************
* int main(void)
* 功能 演示进程创建
*
* 参数 未使用
*************************************
*/
int main()
{
CreateChildProcess(
"Child.exe abc 123");
}
/*************************************
* DWORD CreateChildProcess(LPSTR szChildProcessCmd)
* 功能 演示创建子进程
*
* 参数 LPSTR szChildProcessCmd 启动子进程的命令行
* 返回值 成功返回,失败返回
*************************************
*/
DWORD CreateChildProcess(LPSTR szChildProcessCmd)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
// 将启动信息结构清零
ZeroMemory( &si, sizeof(si) );
// 设置结构大小,cb属性应为结构的大小
si.cb = sizeof(si);
// 将进程信息结构清零
ZeroMemory( &pi, sizeof(pi) );

// 创建子进程,并判断是否成功
if( !CreateProcess( NULL, // 使用命令行
szChildProcessCmd, // 命令行
NULL, // 不继承进程句柄
NULL, // 不继承线程句柄
FALSE, // 不继承句柄
0, // 没有创建标志
NULL, // 使用父进程环境变量
NULL, // 使用父进程目录作为当前目录
&si, // STARTUPINFO 结构
&pi ) // PROCESS_INFORMATION 保存相关信息
)
{
// 创建失败
printf( "CreateProcess failed (%d).\n", GetLastError() );
return 1;
}
// 在创建成功后父进程也可直接退出,这里等待子进程执行结束

// 等待子进程结束
// 使用到了通过PROCESS_INFORMATION 返回的相关信息,hProcess为子进程句柄
// 父进程也可以不等待子进程运行完成而直接退出
WaitForSingleObject( pi.hProcess, INFINITE );
// 关闭进程句柄和线程句柄
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
return 0;
}

创建线程示例

创建线程示例

**************************************/
/* 头文件 */
#include
<windows.h>
#include
<stdio.h>
/* 常量定义 */
#define MAX_THREADS 5
/* 结构类型 */
typedef
struct _THREAD_PARAM {
DWORD i;
DWORD dwRandom;
DWORD dwData;
} THREAD_PARAM,
*LPTHREAD_PARAM;

/*************************************
* DWORD WINAPI ThreadProc( LPVOID lpParam )
* 功能 线程函数
* 将参数打印出
*
* 参数 LPVOID lpParam THREAD_PARAM 结构类型
*************************************
*/
DWORD WINAPI ThreadProc( LPVOID lpParam )
{
LPTHREAD_PARAM pData;
// 参数数据类型
pData = (LPTHREAD_PARAM)lpParam;
// 显示参数
printf("TID = %u,\t Parameters = %u, %u, %u\n",
GetCurrentThreadId(),
pData
->i, pData->dwRandom, pData->dwData);
// 释放保存参数的内存(在主线程中分配的).
HeapFree(GetProcessHeap(), 0, pData);
return 0;
}
/*************************************
* void main()
* 功能 主线程函数,创建了多个线程
*************************************
*/
void main()
{
LPTHREAD_PARAM pData;
DWORD dwThreadId[MAX_THREADS];
HANDLE hThread[MAX_THREADS];
int i;

// 创建MAX_THREADS 个线程.
for( i=0; i<MAX_THREADS; i++ )
{
// 为线程函数参数分配内存
pData = (LPTHREAD_PARAM)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(THREAD_PARAM));
if( pData == NULL )
{
printf(
"HeapAlloc error;\n");
ExitProcess(
2);
}
// 设置参数
pData->i = i;
pData
->dwRandom = rand();
pData
->dwData = 100;
// 创建线程
hThread[i] = CreateThread(
NULL,
// 默认安全属性
0, // 默认堆栈大小
ThreadProc, // 线程函数
pData, // 参数
0, // 默认创建标志
&dwThreadId[i]); // 返回TID
// 判断是否创建成功
if (hThread[i] == NULL)
{
ExitProcess(i);
}
}
}

三、进程状态信息

两类API

进程状态帮助(Process Status Helper,PSAPI),工具帮助(Tool helper)两类API

PSAPI

http://msdn.microsoft.com/en-us/library/ms684884%28VS.85%29.aspx

Tool helpr API:

http://msdn.microsoft.com/en-us/library/ms686832%28VS.85%29.aspx

Dynamic-Link Library Functions

http://msdn.microsoft.com/en-us/library/ms682599%28VS.85%29.aspx

导出dll有两种方法:

一是在函数声明是使用__declspec(dllexport)关键字;

二是在模块定义文件(.def)中进行说明。

参考

[1] 精通Windows API

 

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
c#中跨线程调用windows窗体控件
c#中如何跨线程调用windows窗体控件? 我们在做winform应用的时候,大部分情况下都会碰到使用多线程控制界面上控件信息的问题。然而我们并不能用传统方法来做这个问题,下面我将详细的介绍。首先来看传统方法: public partial class Form1 : Form...
1012 0
温故而知新:WinForm/Silverlight多线程编程中如何更新UI控件的值
单线程的winfom程序中,设置一个控件的值是很easy的事情,直接 this.TextBox1.value = "Hello World!";就搞定了,但是如果在一个新线程中这么做,比如: private void btnSet_Click(object sender, EventArgs e...
770 0
windows下bat批处理实现守护进程
本文转自网络,由于找不到原作者,因而无法知道出处。如果有幸让原作者看到,请联系我加上。先转载至此。 最近几天加班加疯掉了,天天晚上没法睡。开发部的一个核心程序总是会自己宕机,然后需要手工去起,而这个服务的安全级别又很高,只有我可以操作,搞得我晚上老没法睡,昨晚实在受不了了,想起以前在hp-ux下写的shell守护进程,这回搞个windows下的bat版守护程序吧,当时晚上思路已经很迟钝了,就叫了个兄弟让他写了,上去后运行效果不错,至少昨晚我安心睡了7小时。
451 0
java多线程之:线程对象一些api
一:wait()方法,wait(long timeout)--->锁对象调用wait()方法,让当前线程小a进入等待状态,阻塞住,并让出当先线程拥有的锁。--->直到其他线程用锁对象调用notifyAll(),notify()将小a从wait虚拟队列中将阻塞的线程唤醒。
654 0
面试总结-进程、线程与多线程
线程、进程和多线程是面试过程中很容易遇到的问题,去年百度三面的时候就遇到这个问题,当时百度hr问到:线程和进程的区别是什么?你写过多进程或者多线程的程序吗?在你看来多线程和多进程程序那种程序比较难写? 第一个问题很常规,但是要完全答对却不是那么容易,现在想来,第二个问题和第三个问题实际是一个问题,因为第三个问题是验证第二个问题是否说实话的最好的方式。
1275 0
C#线程访问winform窗体控件
参考地址:http://www.cnblogs.com/jason-liu-blogs/archive/2012/09/08/2677008.html 添加: public Form() { InitializeComponent(); Control.
577 0
+关注
582
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载