简体   繁体   English

在Delphi中,OutputDebugString线程安全吗?

[英]In Delphi, is OutputDebugString thread safe?

Is

OutputDebugString(PAnsiChar(''));

thread safe? 线程安全?

I/we have been using it in threads for debugging, and it never occurred to me if I should be doing it a different way. 我/我们一直在线程中使用它来进行调试,如果我以不同的方式做这件事我就不会想到它。

(Delphi 7) (德尔福7)

Well, not that it isn't true, it is, but just so that you don't have to just take Lieven word for it: 嗯,不是说它不是真的,它是,但只是为了让你不必只是为了它而得到Lieven的话:

Passing of data between the application and the debugger is done via a 4kbyte chunk of shared memory, with a Mutex and two Event objects protecting access to it. 应用程序和调试器之间的数据传递是通过一个4k字节的共享内存块完成的,其中一个Mutex和两个Event对象保护对它的访问。 These are the four kernel objects involved. 这些是涉及的四个内核对象。

Understanding Win32 OutputDebugString is an excellent article on the matter. 了解Win32 OutputDebugString是一篇很好的文章。

Don't worry, it is. 别担心,确实如此。

When OutputDebugString() is called by an application, it takes these steps. 当应用程序调用OutputDebugString()时,它将采取这些步骤。 Note that a failure at any point abandons the whole thing and treats the debugging request as a no-op (the string isn't sent anywhere). 请注意,任何时候的失败都会放弃整个过程并将调试请求视为无操作(字符串不会在任何地方发送)。

  1. Open DBWinMutex and wait until we have exclusive access to it. 打开DBWinMutex并等到我们拥有它的独占访问权限。
  2. Map the DBWIN_BUFFER segment into memory: if it's not found, there is no debugger running so the entire request is ignored. 将DBWIN_BUFFER段映射到内存中:如果找不到,则没有调试器运行,因此忽略整个请求。
  3. Open the DBWIN_BUFFER_READY and DBWIN_DATA_READY events. 打开DBWIN_BUFFER_READY和DBWIN_DATA_READY事件。 As with the shared memory segment, missing objects mean that no debugger is available. 与共享内存段一样,缺少对象意味着没有可用的调试器。
  4. Wait for the DBWIN_BUFFER_READY event to be signaled: this says that the memory buffer is no longer in use. 等待DBWIN_BUFFER_READY事件发出信号:这表示内存缓冲区已不再使用。 Most of the time, this event will be signaled immediately when it's examined, but it won't wait longer than 10 seconds for the buffer to become ready (a timeout abandons the request). 大多数情况下,此事件将在检查时立即发出信号,但缓冲区不会等待超过10秒(超时放弃请求)。
  5. Copy up to about 4kbytes of data to the memory buffer, and store the current process ID there as well. 将最多约4k字节的数据复制到内存缓冲区,并将当前进程ID存储在那里。 Always put a NUL byte at the end of the string. 始终在字符串的末尾放置一个NUL字节。
  6. Tell the debugger that the buffer is ready by setting the DBWIN_DATA_READY event. 通过设置DBWIN_DATA_READY事件告诉调试器缓冲区已准备就绪。 The debugger takes it from there. 调试器从那里获取它。
  7. Release the mutex 释放互斥锁
  8. Close the Event and Section objects, though we keep the handle to the mutex around for later. 关闭Event和Section对象,尽管我们将句柄保持在互斥体上以便以后使用。

I've had trouble once, though, with strings in an ISAPI DLL. 不过,我曾经遇到过ISAPI DLL中的字符串问题。 For some odd reason the IsMultiThread boolean defined in System.pas was not set! 由于一些奇怪的原因,未设置System.pas中定义的IsMultiThread布尔值!

It was causing weird AccessViolations, once the thread was running more than one thread... A simple "IsMultiThread:=true;" 一旦线程运行多个线程,它就会导致奇怪的AccessViolations ...一个简单的“IsMultiThread:= true;” in a unit initialization fixed it. 在单元初始化中修复它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM