[笔记]Windows核心编程《十二》纤程

简介: [笔记]Windows核心编程《十二》纤程

前言

目的:

为了更容易将已有的UNIX服务器应用迁移到Windows,增加了纤程。

UNIX应用程序的开发人员创建了线程包,来实现类似线程功能。

使用纤程

  • 线程在windows内核中实现的。
  • 纤程是在用户模式下实现的。
  • 内核仅能调度线程,而纤程由我们调度
  • 一个线程可包含多个纤程。

将一个已有的线程转换为一个纤程

一个已有的线程转换为一个纤程

PVOID ConvertThreadToFiber(PVOID pvParam);

如果函数成功,返回值是纤维的地址;如果函数失败,返回值是零。

这个函数为纤程的执行上下文CONTEXT分配内存。

执行上下文一般包含:

  • 一个用户自定义的值(pvParam)
  • 结构化异常处理链的头
  • 纤程栈的顶部和底部的内存地址
  • 某些CPU寄存器,包括栈指针,指令指针以及其他寄存器

默认情况下x86系统中CPU的浮点状态信息不属于CPU寄存器的一部分,不会为每个纤程都维护一份,而如果纤程要执行浮点操作,那会导致数据被破坏。

为了覆盖系统的默认行为需要使用新的ConvertThreadToFiberEx函数

允许传入FIBER_FLAG_FLOAT_SWITCH标志:

WINBASEAPI
_Ret_maybenull_
LPVOID
WINAPI
ConvertThreadToFiberEx(
    _In_opt_ LPVOID lpParameter,
    _In_     DWORD dwFlags
    );

除非打算在一个线程中执行多个纤程,否则只为执行一个任务,而将线程转换为纤程没有任何意义。

在当前线程中创建另一个纤程

WINBASEAPI
_Ret_maybenull_
LPVOID
WINAPI
CreateFiber(
    _In_     SIZE_T dwStackSize,
    _In_     LPFIBER_START_ROUTINE lpStartAddress,
    _In_opt_ LPVOID lpParameter
    );

如果要使用大量的纤程,希望纤程消耗更少的内存使用下列函数来创建纤程。

WINBASEAPI
_Ret_maybenull_
LPVOID
WINAPI
CreateFiberEx(
    _In_     SIZE_T dwStackCommitSize,
    _In_     SIZE_T dwStackReserveSize,
    _In_     DWORD dwFlags,
    _In_     LPFIBER_START_ROUTINE lpStartAddress,
    _In_opt_ LPVOID lpParameter
    );

dwStackCommitSize:设置一开始要调拨的物理存储页。

dwStackReservesize: 运行我们预定指定的虚拟内存。

dwFlags:可以接受FIBER_FLAG_FLOAT_SWITCH将浮点运算状态保留。

lpfnStartAddress:用来指定纤程函数的地址。例如以下就是定义一个纤程函数。

VOID WINAPI FiberFunc(PVOID pvParam);

其他参数和CreateFiber相同。

CreateFiber返回的是为纤程创建的CONTEXT的地址(和ConvertThreadToFiber类似)

但是CreateFiber创建的新纤程默认不会执行。(因为一个线程中只能执行一个纤程)

需要调用SwitchToFiber来切换纤程

WINBASEAPI
VOID
WINAPI
SwitchToFiber(
    _In_ LPVOID lpFiber
    );

lpFiber是用CreateFiber或ConvertThreadToFiber返回的值,告诉函数要调用哪个纤程。SwitchToFiber会执行以下步骤:

1)将一些cpu寄存器目前的值,其中包括指令指针(IP)寄存器和栈指针寄存器(SP) 保存在当前运行的纤程的CONTEXT中

2)从即将运行的纤程的执行CONTEXT中载入先前保存的寄存器值并载入cpu

这些寄存器中包含栈指针寄存器,这样单线程继续执行就会使用新纤程的栈。

3)将新纤程的执行CONTEXT和线程关联,让线程运行指定的纤程。

4)将线程的指令指针设为先前保存的指令指针(IP),这样线程(纤程)就会从上次执行的地方开始继续往下执行。

SwitchToFiber是让纤程得到cpu时间切片的唯一方法。所以纤程的调度完全由我们自己掌控。

调用DeleteFiber来销毁纤程

WINBASEAPI
VOID
WINAPI
DeleteFiber(
    _In_ LPVOID lpFiber
    );

lpFiber是纤程的CONTEXT地址。该函数会删除参数所表示的纤程。如果线程和纤程绑定了,其内部会调用ExitThread同时销毁当前的线程。

(TerminateThread不会销毁线程栈)

将转成了纤程的线程转回来。

ConvertTiberToThread(Ex)

如果为纤程保存一些信息可以使用纤程局部存储区(Fiber Local Storage, FLS)函数

其他纤程相关的函数

获得纤程执行的上下文

PVOID GetCurrentFiber();

返回纤程的用户自定义值(CreateFiber所传递的pvParam)

PVOID GetFiberData();

Counter示例程序

相关:

参考1

参考2


相关文章
|
20天前
|
缓存 网络协议 数据安全/隐私保护
[运维笔记] - (命令).Windows server常用网络相关命令总结
[运维笔记] - (命令).Windows server常用网络相关命令总结
218 0
|
7月前
|
消息中间件 C++ Windows
02 MFC - Windows 编程模型
02 MFC - Windows 编程模型
22 0
|
9天前
|
编解码 5G Linux
FFmpeg开发笔记(二十一)Windows环境给FFmpeg集成AVS3解码器
AVS3是中国首个8K及5G视频编码标准,相比AVS2和HEVC性能提升约30%。解码器libuavs3d支持8K/60P视频实时解码,兼容多种平台。《FFmpeg开发实战》书中介绍了在Windows环境下如何集成libuavs3d到FFmpeg。集成步骤包括下载源码、使用Visual Studio 2022编译、调整配置、安装库文件和头文件,以及重新配置和编译FFmpeg以启用libuavs3d。
27 0
FFmpeg开发笔记(二十一)Windows环境给FFmpeg集成AVS3解码器
|
20天前
|
算法 Linux Windows
FFmpeg开发笔记(十七)Windows环境给FFmpeg集成字幕库libass
在Windows环境下为FFmpeg集成字幕渲染库libass涉及多个步骤,包括安装freetype、libxml2、gperf、fontconfig、fribidi、harfbuzz和libass。每个库的安装都需要下载源码、配置、编译和安装,并更新PKG_CONFIG_PATH环境变量。最后,重新配置并编译FFmpeg以启用libass及相关依赖。完成上述步骤后,通过`ffmpeg -version`确认libass已成功集成。
31 1
FFmpeg开发笔记(十七)Windows环境给FFmpeg集成字幕库libass
|
20天前
|
编解码 Linux Windows
FFmpeg开发笔记(十三)Windows环境给FFmpeg集成libopus和libvpx
本文档介绍了在Windows环境下如何为FFmpeg集成libopus和libvpx库。首先,详细阐述了安装libopus的步骤,包括下载源码、配置、编译和安装,并更新环境变量。接着,同样详细说明了libvpx的安装过程,注意需启用--enable-pic选项以避免编译错误。最后,介绍了重新配置并编译FFmpeg以启用这两个库,通过`ffmpeg -version`检查是否成功集成。整个过程参照了《FFmpeg开发实战:从零基础到短视频上线》一书的相关章节。
37 0
FFmpeg开发笔记(十三)Windows环境给FFmpeg集成libopus和libvpx
|
20天前
|
Rust 前端开发 Windows
blog-engine-06-pelican 静态网站生成 windows11 安装实战笔记
这篇内容是一个关于在Windows 11上安装和使用静态网站生成器的教程,主要包括对多个博客引擎(如Jekyll、Hugo、Hexo等)的简介和对比,以及详细步骤教你如何在Windows环境下安装Python、Pelican、Rust和Cargo。作者首先介绍了Python和Pelican的安装,然后在遇到依赖问题时,引导读者安装Rust和Cargo来解决。最后,通过`pelican-quickstart`创建项目,编写Markdown文章并生成、预览站点。
|
20天前
|
编解码 Linux Windows
FFmpeg开发笔记(十一)Windows环境给FFmpeg集成vorbis和amr
在Windows环境下,为FFmpeg集成音频编解码库,包括libogg、libvorbis和opencore-amr,涉及下载源码、配置、编译和安装步骤。首先,安装libogg,通过配置、make和make install命令完成,并更新PKG_CONFIG_PATH。接着,安装libvorbis,同样配置、编译和安装,并修改pkgconfig文件。之后,安装opencore-amr。最后,重新配置并编译FFmpeg,启用ogg和amr支持,通过ffmpeg -version检查是否成功。整个过程需确保环境变量设置正确,并根据路径添加相应库。
39 1
FFmpeg开发笔记(十一)Windows环境给FFmpeg集成vorbis和amr
|
20天前
|
API C++ Windows
windows编程入门_链接错误的配置
windows编程入门_链接错误的配置
20 0
|
20天前
|
机器学习/深度学习 安全 数据安全/隐私保护
Windows系统安装Jupyter Notebook并实现公网访问内网笔记服务
Windows系统安装Jupyter Notebook并实现公网访问内网笔记服务
|
20天前
|
Linux 编译器 C语言
FFmpeg开发笔记(二)搭建Windows系统的开发环境
在Windows上学习FFmpeg通常较困难,但通过安装预编译的FFmpeg开发包可以简化流程。首先需要安装MSYS2来模拟Linux环境。下载并执行MSYS2安装包,然后修改msys2_shell.cmd以继承Windows的Path变量。使用pacman安装必要的编译工具。接着,下载预编译的FFmpeg Windows包,解压并配置系统Path。最后,在MSYS2环境中运行`ffmpeg -version`确认安装成功。欲深入学习FFmpeg开发,推荐阅读《FFmpeg开发实战:从零基础到短视频上线》。
42 4
FFmpeg开发笔记(二)搭建Windows系统的开发环境