gpt4 book ai didi

c++ - 如何安全地与不同编译单元中的线程共享变量?

转载 作者:行者123 更新时间:2023-11-28 08:18:31 26 4
gpt4 key购买 nike

在我的程序结构中,我将“从哪里调用它”和“完成什么”分成单独的源文件。实际上,这允许我将程序编译为独立程序或将其包含在 DLL 中。下面的代码不是实际代码,而是表达相同观点的简化示例。

这里有 3 个交互组件:加载我的 DLL 的内核模式程序、DLL 及其源文件和实用程序及其源,它们是单独维护的。

在DLL形式中,程序是作为线程加载的。根据内核模式应用程序供应商的文档,我在内核程序初始化后失去了调用 Win32 API 函数的能力,因此我将线程加载为事件线程(而不是使用 CREATE_SUSPENDED,因为我无法唤醒它)。

我让它监视一个标志变量,这样它就知道什么时候通过一个不优雅但实用的东西来做一些有用的事情:

while ( pauseThreadFlag ) Sleep(1000);

最多 1 秒的延迟是可以接受的(整个过程很长,而且很少调用)并且似乎不会影响系统。

在线程源文件中我将变量声明为

volatile bool pauseThreadFlag = true;

在我声明的 DLL 源文件中

extern volatile bool pauseThreadFlag;

当我准备好让线程执行时,在我设置的 DLL 中

pauseThreadFlag = false;

我在将 std::string 对象声明为 volatile 时遇到了一些困难,因此我在线程的源文件中将我的参数声明为全局变量,并让 DLL 调用 setter 驻留在线程的源中。如果我可以随意实例化线程,这些字符串将成为参数。

(所有这些都缺少为线程安全锁定变量,这是我的下一个“要做的事”)

这让我觉得这是一个糟糕的设计……它很实用但很复杂。考虑到我提到的限制,是否有更好的方法来解决这个问题?

我在想一个可能的修改是使用线程创建时给出的 LPVOID lpParams 变量来保存指向字符串对象的指针,即使在创建线程时字符串为空,并直接从线程访问它们, 那种方式完全删除线程程序中的声明、setter 等?如果这可行,那么也可以在那里引用暂停标志,并消除外部声明(但我认为它仍然需要声明为 volatile 以提示优化器)。

如果有区别,环境是Visual Studio 2010,C++,目标平台Win32(XP)。

谢谢!

最佳答案

如果所有组件都在内核模式下运行,您将需要查看 KeInitializeEvent , KeSetEvent , KeResetEventKeWaitForSingleObject .这些都以与其等效的用户模式类似的方式工作。

关于c++ - 如何安全地与不同编译单元中的线程共享变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6768453/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com