杀死正在执行 memcpy 的线程是不是安全?
Posted
技术标签:
【中文标题】杀死正在执行 memcpy 的线程是不是安全?【英文标题】:Is it safe to kill a thread that is executing a memcpy?杀死正在执行 memcpy 的线程是否安全? 【发布时间】:2018-02-10 18:53:17 【问题描述】:上下文:
我正在开发一个需要快速访问大文件的应用程序,因此我使用了内存映射。结果,阅读和写作变成了一个简单的memcpy
。我现在正在尝试添加中止任何正在进行的读取或写入的功能。
首先想到的(因为我不知道任何可中断的 memcpy 函数)是定期memcpy
几个 KB 并检查是否应该中止操作。如果读取速度相当快,这应该可以确保近乎即时的流产。
如果不是,那么应用程序不应该花费很长时间才能中止,所以我的第二个想法是使用多线程。 memcpy 发生在它自己的线程中,控制线程使用WaitForMultipleObjects
处理一个表明流产的事件,以及 memcpy 线程。如果发出了流产事件的信号,它将杀死 memcpy 线程。但是,documentation on TerminateThread 声明应该绝对确保不会因为不释放资源而使系统处于不良状态。
问题:
在复制映射内存时,memcpy 是否会导致杀死它不安全?这样做安全吗?它是否依赖于实现(使用不同于 Windows x86-64 的操作系统/架构)?
我确实意识到使用第二种方法可能完全是矫枉过正,因为实际上没有 1KB 读/写会花费那么长时间,但我只想安全。
【问题讨论】:
有一种观点认为你不应该终止线程。 考虑将memcpy
以合理大小(例如兆字节)的块进行,其副本通常会持续几毫秒。您可以在复制一些原子标志之后进行测试,或者使用互斥锁等保护该副本......并围绕它进行循环。
这家伙比我知道(很多)“还有人认为调用 TerminateThread 有有效的场景。”:blogs.msdn.microsoft.com/oldnewthing/20150814-00/?p=91811
好的,所以我想这个故事的寓意是:“memcpy 无关紧要,TerminateThread 只是一个可怕的想法”?那就轮询吧!
如果您将使用 ReadFile/WriteFile 代替异步文件句柄,您可以随时中断/取消读/写操作
【参考方案1】:
如果可能你应该选择不同的设计,TerminateThread
不应该被认为是一个正常的功能,它更多的是用于调试/电动工具。
我建议您围绕 memcpy
创建一个包装器,以块的形式进行复制。块大小实际上取决于您,取决于您的响应能力要求。 1 MiB 可能是一个很好的起点。
如果您绝对想杀死线程,您必须考虑以下几点:
您显然不知道memcpy
在内部是如何工作的,也不知道它复制了多少,因此您必须假设在中止时整个范围都未定义。
在某些版本的 Windows 上终止线程会泄漏内存。有workarounds。
不要在线程中持有任何锁。
【讨论】:
以上是关于杀死正在执行 memcpy 的线程是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章
什么是现代的、可移植的、安全的等价于 C 中编译时检查的 memcpy?