windows线程的相关概念

windows线程的相关概念

线程

进程是由两个部分构成的,一个是进程内核对象,另一个是地址空间。同样,
线程也是由两个部分组成的:

  • 一个是线程的内核对象,操作系统用它来对线程实施管理。内核对象也是系统用来存放线程统计信息的地方。

  • 另一个是线程堆栈,它用于维护线程在执行代码时需要的所有函数参数和局部变量

由于线程需要的开销比进程少,因此始终都应该设法用增加线程来解决编程问题,而要避免创建新的进程。但是,这个建议并不是一成不变的。许多程序设计用多个进程来实现会更好些。

何时创建线程

线程用于描述进程中的运行路径。每当进程被初始化时,系统就要创建一个主线程。该线程与C / C + +运行期库的启动代码一道开始运行,启动代码则调用进入点函数(main、 wmain、WinMain或wWinMain),并且继续运行直到进入点函数返回并且 C / C + +运行期库的启动代码调用ExitProcess为止。对于许多应用程序来说,这个主线程是应用程序需要的唯一线程。不过,进程能够创建更多的线程来帮助执行它们的操作。

何时不能创建线程

然多线程应用程序的优点很多,但是它也存在某些不足之处。 应该慎重地使用多线程。不要想用就用。仅仅使用赋予进程的主线程,就能够编写出许多非常有用的和功能强大的应用程序 。

编写线程函数

每个线程必须拥有一个进入点函数,线程从这个进入点开始运行。前面已经介绍了主线程的进入点函数:即 main、 wmain、 WinMain或wWinMain。如果想要在你的进程中创建一个辅助线程,它必定也是个进入点函数。

下面对线程函数的几个问题作一说明:

  • 主线程的进入点函数的名字必须是m a i n、 w m a i n、 Wi n M a i n或w Wi n M a i n,与这些函数不同的是,线程函数可以使用任何名字。实际上,如果在应用程序中拥有多个线程函数,必须为它们赋予不同的名字,否则编译器/链接程序会认为你为单个函数创建了多个实现函数。
  • 由于给你的主线程的进入点函数传递了字符串参数,因此可以使用 A N S I / U n i c o d e版本的
    进入点函数: m a i n / w m a i n和Wi n M a i n / w Wi n M a i n。可以给线程函数传递单个参数,参数的含义由你而不是由操作系统来定义。因此,不必担心 A N S I / U n i c o d e问题。
  • 线程函数必须返回一个值,它将成为该线程的退出代码。这与 C / C + +运行期库关于让主线程的退出代码作为进程的退出代码的原则是相似的。
  • 线程函数(实际上是你的所有函数)应该尽可能使用函数参数和局部变量。当使用静态变量和全局变量时,多个线程可以同时访问这些变量,这可能破坏变量的内容。然而,参数和局部变量是在线程堆栈中创建的,因此它们不太可能被另一个线程破坏。

CreateThread函数

如果想要创建一个或多个辅助函数,只需要让一个已经在运行的线程来调用 CreateThread :

HANDLE CreateThread(
    LPSECURITY_ATTRIBUTES lpThreadAttributes,//SD
    SIZE_T dwStackSize,//initialstacksize
    LPTHREAD_START_ROUTINE lpStartAddress,//threadfunction
    LPVOID lpParameter,//threadargument
    DWORD dwCreationFlags,//creationoption
    LPDWORD lpThreadId//threadidentifier
);

当C r e a t e T h r e a d被调用时,系统创建一个线程内核对象。该线程内核对象不是线程本身,而是操作系统用来管理线程的较小的数据结构。可以将线程内核对象视为由关于线程的统计信息组成的一个小型数据结构。这与进程和进程内核对象之间的关系是相同的。

系统从进程的地址空间中分配内存,供线程的堆栈使用。新线程运行的进程环境与创建线程的环境相同。因此,新线程可以访问进程的内核对象的所有句柄、进程中的所有内存和在这个相同的进程中的所有其他线程的堆栈。这使得单个进程中的多个线程确实能够非常容易地互相通信。

终止线程的运行

若要终止线程的运行,可以使用下面的方法:
• 线程函数返回(最好使用这种方法)。
• 通过调用E x i t T h r e a d函数,线程将自行撤消(最好不要使用这种方法)。
• 同一个进程或另一个进程中的线程调用 Te r m i n a t e T h r e a d函数(应该避免使用这种方法)。
• 包含线程的进程终止运行(应该避免使用这种方法)。

猜你喜欢

转载自blog.csdn.net/libing403/article/details/78282892