三、 Windows里面的进程(Process)和线程(Thread)

原创 2018年04月16日 14:57:48

首先,我们应该知道,windows调度的单位是线程而不是进程!


从而,我们认识一下核心对象(系统资源)
这里写图片描述


进程的生死周期:
这里写图片描述
当然,你也可以编写一个程序,使用CreateProcess函数创建一个新的进程去调用其他的程序。

BOOL CreateProcess(
  LPCTSTR lpApplicationName, // pointer to name of executable module
  LPTSTR lpCommandLine,  // pointer to command line string
  LPSECURITY_ATTRIBUTES lpProcessAttributes,  // process security attributes
  LPSECURITY_ATTRIBUTES lpThreadAttributes,   // thread security attributes
  BOOL bInheritHandles,  // handle inheritance flag
  DWORD dwCreationFlags, // creation flags
  LPVOID lpEnvironment,  // pointer to new environment block
  LPCTSTR lpCurrentDirectory,   // pointer to current directory name
  LPSTARTUPINFO lpStartupInfo,  // pointer to STARTUPINFO
  LPPROCESS_INFORMATION lpProcessInformation  // pointer to PROCESS_INFORMATION
);

以下是《深入浅出MFC中的参数解析》,详细的可查MSDN
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
按理来说,shell创建了一个新进程,那么他就是shell的子进程了,然而实际上,shell在创建了一个新进程之后,它就切断了该进程与自己的父子关系,如下使用CloseHandle就可以实现上面的操作:
这里写图片描述


线程的生死周期:
这里写图片描述
我们使用CreateThread函数创建一个线程在调用进程的地址空间。

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES lpThreadAttributes,  // 线程的安全属性
  DWORD dwStackSize,                         // 初始化线程的栈大小
  LPTHREAD_START_ROUTINE lpStartAddress,     // 线程需要处理的函数(content)
  LPVOID lpParameter,                        // 线程处理函数的参数
  DWORD dwCreationFlags,                     // 线程创建的附加标识
  LPDWORD lpThreadId                         // 返回线程的id
);

下面是MSDN里面的参数解析
Parameters
lpThreadAttributes
指向一个SECURITY_ATTRIBUTES 结构的 that确定返回的句柄是否可以由子进程继承。如果被子进程是null,手柄不能被继承。
Windows NT: 该结构的lpSecurityDescriptor成员指定为新的线程安全描述符。如果被子进程是空的,线程获取默认安全描述符.
dwStackSize
指定堆栈的初始提交大小,以字节为单位。系统将该值旋转到最近的页面。如果该值为零,或者小于默认提交大小,则默认使用与调用线程相同的大小。有关更多信息,请参见线程堆栈大小.
lpStartAddress
应用程序定义的函数指针类型LPTHREAD_START_ROUTINE被线程执行的线程的起始地址。在线程函数的更多信息。
lpParameter
指定传递给线程的单个32位参数值。
dwCreationFlags
指定控制线程创建的附加标志。如果create_suspended标志指定, 线程处于挂起状态了,也不会跑到resumethread函数被调用。如果此值为零,则线程在创建后立即运行。此时,没有其他值被支持。
lpThreadId
指向接收线程标识符的32位变量的指针。.
Windows NT:如果此参数为空,则不返回线程标识符。
Windows 95和Windows 98:此参数可能不是null。
返回值:
如果函数创建成功,则返回该线程句柄,如果失败,返回NULL。错误信息调取函数GetLastError。

与此同时,我们不能忘了C runtime函数库里面也有一个创建线程的方法:_beginthreadex

uintptr_t _beginthread( // NATIVE CODE  
   void( __cdecl *start_address )( void * ),  
   unsigned stack_size,  
   void *arglist   
);  
uintptr_t _beginthread( // MANAGED CODE  
   void( __clrcall *start_address )( void * ),  
   unsigned stack_size,  
   void *arglist   
);  
uintptr_t _beginthreadex( // NATIVE CODE  
   void *security,  
   unsigned stack_size,  
   unsigned ( __stdcall *start_address )( void * ),  
   void *arglist,  
   unsigned initflag,  
   unsigned *thrdaddr   
);  
uintptr_t _beginthreadex( // MANAGED CODE  
   void *security,  
   unsigned stack_size,  
   unsigned ( __clrcall *start_address )( void * ),  
   void *arglist,  
   unsigned initflag,  
   unsigned *thrdaddr   
);  

参数
start_address
启动开始执行新线程的例程的地址。 对于 _beginthread,调用约定是 __cdecl (针对本机代码)或 __clrcall (针对托管代码);对于_beginthreadex,它是 __stdcall (针对本机代码)或 __clrcall (针对托管代码)。
stack_size
新线程的堆栈大小或 0。
arglist
要传递到新线程的参数列表或 NULL。
Security
指向 SECURITY_ATTRIBUTES 结构的指针,此结构确定返回的句柄是否由子进程继承。 如果 Security 为 NULL,则不能继承句柄。 对于 Windows 95 应用程序,必须为 NULL。
initflag
控制新线程的初始状态的标志。 将 initflag 设置为 0 以立即运行,或设置为 CREATE_SUSPENDED 以在挂起状态下创建线程;使用 ResumeThread来执行此线程。 将 initflag 设置为 STACK_SIZE_PARAM_IS_A_RESERVATION 标志以将 stack_size 用作堆栈的初始保留大小(以字节计);如果未指定此标志, stack_size 将指定提交大小。
thrdaddr
指向接收线程标识符的 32 位变量。 如果此变量为 NULL,则不可用。
返回值
如果成功,则这些函数中的每一个都会返回一个句柄到新创建的线程;但是,如果新创建的线程退出过快,则 _beginthread 可能不会返回有效句柄。 (请参见“备注”节中的讨论。)发生错误时,_beginthread 返回 -1L,并在线程过多的情况下将 errno 设置为 EAGAIN;如果参数无效或堆栈大小错误,则设置为 EINVAL;如果资源(如内存)不足,则设置为 EACCES。 发生错误时, _beginthreadex 返回 0 并设置 errno 和 _doserrno 。
如果 startaddress 为 NULL,则会调用无效的参数处理程序,如 Parameter Validation所述。 如果允许执行继续,则这些功能将 errno 设置为EINVAL 并返回 -1。


线程优先级:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
总结来看,其优先级可以看做:
这里写图片描述

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huichangxindong/article/details/79960693

理解process(进程)、thread(线程)

理解process(进程)、thread(线程)
  • chenjiaxiang520
  • chenjiaxiang520
  • 2016-12-17 13:33:57
  • 491

【os学习】之 进程(Process)与线程(Thread)

一、进程(Process)  ①定义:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。  ② 进程控制块:配置一个专门的数据结构——进程控制块(Process Control Blo...
  • fanfan4569
  • fanfan4569
  • 2017-03-25 16:21:15
  • 379

进程 (process)和 线程 (thread)是操作系统的基本概念

进程 (process)和 线程 (thread)是操作系统的基本概念,但是它们比较抽象,不容易掌握。我发现有一个很好的类比,可以把它们解释地清晰易懂。 计算机的核心是CPU,它承担...
  • u012878609
  • u012878609
  • 2015-11-05 18:09:16
  • 327

进程(Process)和线程(Thread)的关系和区别

 Definition定义 ------------- Process 进程是应用程序的一次运行活动; 从操作系统核 心角度来说,进程是操作系统分配和调度系统内存资源、cpu时间片等资源...
  • honglin_ren
  • honglin_ren
  • 2014-06-29 22:23:34
  • 2813

Loadrunner Vuser线程与进程的区别

在Loadrunner中,Vuser有两种运行方式,线程Thread和进程Process。由于线程会共享资源,因此线程方式比较节省负载机资源,但是用Java Vuser时,二者在使用上有所差别,需加注...
  • genius5200
  • genius5200
  • 2012-09-02 23:19:42
  • 2788

Process进程 ; Thread线程 (拷贝文件,带进度条的使用实例)

前台线程和后台线程 using System; using System.Collections.Generic; using System.Linq; using System.Text; usi...
  • Fanbin168
  • Fanbin168
  • 2014-12-23 17:37:37
  • 2280

学习笔记之深入浅出MFC 第7章 进程与线程(Process and Thread)

os/2、Windows NT以及Windows 9x都支持多线程,这给程序员带来了很大的便利。然而,在使用多线程的时候,必须要处理好各线程之间的关系,否则会带来很多麻烦。 进程(process)表示...
  • walkman_lfq
  • walkman_lfq
  • 2016-04-22 16:51:41
  • 781

【操作系统】线程与进程的操作(C#)

08年9月入学,12年7月毕业,结束了我在软件学院愉快丰富的大学生活。此系列是对四年专业课程学习的回顾,索引参见:http://blog.csdn.net/xiaowei_cqu/article/de...
  • xiaowei_cqu
  • xiaowei_cqu
  • 2011-12-05 10:20:14
  • 5766

计算机必知必会:进程process与线程thread

进程和线程这对概念的理解也是很难的,至今网络上可查的资料对其的理解出入都挺大,在不同的操作系统中,如linux和windows中,其概念和实现都是有出入的。因此,我在这里结合我自己的理解谈下这两个概念...
  • liuyecao6
  • liuyecao6
  • 2014-04-18 22:32:44
  • 511

67.windbg-!thread、.thread(内核)

!thread扩展显示目标系统中线程包括ETHREAD块在内的摘要信息。该命令只能在内核模式调试下使用 !thread [-p] [-t] [Address [Flags]] -p 显...
  • hgy413
  • hgy413
  • 2014-03-02 23:14:59
  • 4181
收藏助手
不良信息举报
您举报文章:三、 Windows里面的进程(Process)和线程(Thread)
举报原因:
原因补充:

(最多只允许输入30个字)