目录
一、程序与进程的区别
一、定义与概念
二、主要区别
三、总结
二、进程的空间分配
1. 栈区(Stack)
2. 堆区(Heap)
3. 全局区(静态区,Static Area)
4. 文字常量区(Text Constants Area)
5. 程序代码区(Code Area)
总结
三、进程的创建
函数
示例:
四、进程的案例:实现微信双开
一、程序与进程的区别
程序与进程在计算机领域中是两个重要但不同的概念,它们之间的主要区别可以从以下几个方面进行阐述:
一、定义与概念
- 程序(Program):程序是一组有序的计算机指令的集合,通常用某种程序设计语言编写,运行于某种目标计算机体系结构上。程序是静态的,它描述了计算机需要完成的操作序列,但本身并不执行任何操作。程序可以被视为计算机软件的“蓝图”或“食谱”,它告诉计算机如何完成任务,但不会自动执行这些任务。
- 进程(Process):进程是程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单元。换句话说,进程是程序的一次执行实例,它包含了程序计数器、寄存器、堆栈等运行状态信息,以及程序执行所需的数据集合。进程是动态的,它随着程序的执行而创建、运行、暂停和终止。
二、主要区别
- 静态与动态:
- 程序是静态的,它只是一组指令的集合,不包含任何执行状态。
- 进程是动态的,它是程序的一次执行过程,包含了程序的执行状态和数据。
- 存在性与生命周期:
- 程序是永久的,只要不被删除或修改,它就可以长期存储在介质上。
- 进程是暂时的,它具有生命周期,从创建到终止。一旦进程终止,其占用的资源将被释放。
- 执行与调度:
- 程序本身不执行任何操作,需要被加载到内存中并由操作系统调度执行。
- 进程是操作系统调度的基本单位,操作系统通过管理进程来实现对计算机资源的分配和调度。
- 并发与并行:
- 程序本身不具备并发或并行的能力,它只能顺序执行。
- 进程可以并发执行,即多个进程可以同时存在于内存中并交替执行。在某些情况下,多个进程也可以并行执行,即同时占用多个处理器核心进行执行。
- 独立性与资源共享:
- 程序是独立的指令集合,不与其他程序共享资源(除非通过外部机制如文件、网络等)。
- 进程虽然具有一定的独立性(如独立的内存空间),但在某些情况下(如多线程进程)可以共享进程内的资源(如全局变量、文件描述符等)。
三、总结
程序与进程是计算机领域中两个紧密相连但又相互区别的概念。程序是静态的指令集合,而进程是程序的一次动态执行过程。理解这两个概念的区别对于深入理解计算机操作系统和软件开发具有重要意义。在实际应用中,程序员需要编写程序来实现特定的功能,而操作系统则通过管理进程来确保程序的正确执行和资源的高效利用。
二、进程的空间分配
进程的空间分配主要涉及几个关键的内存区域,这些区域从高地址到低地址(或相反,具体取决于操作系统的实现和架构)分布,包括栈区、堆区、全局区(静态区)、文字常量区以及程序代码区。
1. 栈区(Stack)
- 定义与功能:栈区主要用于存储函数调用的局部变量、函数参数、返回地址等信息。它是一个后进先出(LIFO)的数据结构,由编译器自动管理内存的分配和释放。
- 特点:
- 分配速度快,因为栈内存的操作通常有专门的指令支持。
- 空间有限,当栈空间不足时,会导致栈溢出错误。
- 栈是向低地址扩展的数据结构,即新分配的栈空间地址低于旧的栈空间地址。
2. 堆区(Heap)
- 定义与功能:堆区用于存储程序运行过程中动态分配的内存。程序员通过调用如
malloc
、new
等函数在堆上分配内存,并通过free
、delete
等函数释放内存。 - 特点:
- 分配和释放速度相对较慢,因为需要执行额外的管理操作。
- 空间大小灵活,理论上可以扩展到整个可用内存空间。
- 堆是向高地址扩展的数据结构,即新分配的堆空间地址高于旧的堆空间地址。
- 频繁分配和释放不同大小的堆空间容易产生内存碎片。
3. 全局区(静态区,Static Area)
- 定义与功能:全局区用于存储全局变量和静态变量。这些变量在程序的整个运行期间都存在。
- 特点:
- 初始化的全局变量和静态变量存储在
.data
段,未初始化的全局变量和静态变量存储在.bss
段(.bss
段不占用磁盘空间,只在内存中分配)。 - 程序结束后,由操作系统释放这些变量所占用的内存。
- 初始化的全局变量和静态变量存储在
4. 文字常量区(Text Constants Area)
- 定义与功能:文字常量区用于存储字符串常量等文字信息。这些常量在程序编译时就已经确定,并在程序运行过程中保持不变。
- 特点:
- 该区域的内容通常是只读的,以防止程序修改常量值。
- 程序结束后,由操作系统释放该区域所占用的内存。
5. 程序代码区(Code Area)
- 定义与功能:程序代码区用于存储程序的机器指令代码,即程序的二进制可执行代码。
- 特点:
- 该区域的内容在程序运行前就已经确定,并且在程序运行过程中保持不变。
- 该区域通常是只读的,以防止程序意外修改代码。
- 程序结束后,由操作系统回收该区域的内存(但在某些情况下,如共享库,代码区可能不会被立即回收)。
总结
进程的空间分配是一个复杂的过程,涉及多个内存区域的协同工作。每个区域都有其特定的用途和特点,共同支持程序的正常运行。了解这些内存区域的工作原理对于编写高效、稳定的程序至关重要。
此外,需要注意的是,不同的操作系统和编程语言在实现进程空间分配时可能会有所不同。因此,在编写跨平台或特定于语言的程序时,需要仔细考虑这些差异并采取相应的措施来确保程序的正确性和效率。
三、进程的创建
函数
Windows系统中创建进程的API 是CreateProcess.
BOOL CreateProcessA(
[in, optional] LPCSTR lpApplicationName,
[in, out, optional] LPSTR lpCommandLine,
[in, optional] LPSECURITY_ATTRIBUTES lpProcessAttributes,
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] BOOL bInheritHandles,
[in] DWORD dwCreationFlags,
[in, optional] LPVOID lpEnvironment,
[in, optional] LPCSTR lpCurrentDirectory,
[in] LPSTARTUPINFOA lpStartupInfo,
[out] LPPROCESS_INFORMATION lpProcessInformation
);
示例:
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
void _tmain( int argc, TCHAR *argv[] )
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
if( argc != 2 )
{
printf("Usage: %s [cmdline]\n", argv[0]);
return;
}
// Start the child process.
if( !CreateProcess( NULL, // No module name (use command line)
argv[1], // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi ) // Pointer to PROCESS_INFORMATION structure
)
{
printf( "CreateProcess failed (%d).\n", GetLastError() );
return;
}
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
四、进程的案例:实现微信双开
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
//创建进程-- szbuf存储的是微信的安装路径
char szbuf[MAX_PATH] = "D:\\Program Files (x86)\\Tencent\\WeChat\\WeChat.exe";
// [命令+空格+] 文件的名称
STARTUPINFOA si= {sizeof(STARTUPINFOA)};
PROCESS_INFORMATION pi;
CreateProcessA(NULL, //应用程序名称
szbuf, //命令
0, //进程的安全属性
0,//线程的安全属性
0,//继承性
NORMAL_PRIORITY_CLASS,//优先级
0,//环境块
0,//路径
&si,
&pi
);
CreateProcessA(NULL, //应用程序名称
szbuf, //命令
0, //进程的安全属性
0,//线程的安全属性
0,//继承性
NORMAL_PRIORITY_CLASS,//优先级
0,//环境块
0,//路径
&si,
&pi
);
while(1)Sleep(1);
return 0;
}