线程类之外的线程安全例程
如果你有一个调用函数的线程,据我所知,它是任何全局或 VCL 组件调用,这使得它不是线程安全的,对吗?
所以如果你的线程调用这样的方法
procedure UpdateRow()
begin
StringGrid1.AddRow(....);
end;
就不是线程安全的。 但是,如果您有这样的
function ParseXML(const XML : String) : string;
var
xml_parser : TXMLParser;
begin
xml_parser := TXMLParser.create;
... do stuff
result := xml_parser.something;
xml_parser.free;
end;
线程安全方法,只要 TXMLParser 不执行任何非线程安全的操作即可。
但是如果两个线程同时调用该方法,它不会抛出异常,因为它们都创建自己的 TXMLParser 实例,对吧?他们得到自己的副本。这是正确的吗?
希望这是有道理的:)
If you have a thread which calls a function, AFAIK it's any global or VCL component calls which make it not thread safe right?
So if your thread called a method like
procedure UpdateRow()
begin
StringGrid1.AddRow(....);
end;
that is not thread safe.
however if you have a method like this
function ParseXML(const XML : String) : string;
var
xml_parser : TXMLParser;
begin
xml_parser := TXMLParser.create;
... do stuff
result := xml_parser.something;
xml_parser.free;
end;
that is thread safe, as long as the TXMLParser is not doing anything unthread safe.
But if two threads call that method at the same time, it wont throw an exception as they both create their own instance of TXMLParser right? They get their own copy. Is that correct?
Hope that makes sense :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,这是正确的。
Yes, that is correct.
事实上,它可能是正确的,但不一定是正确的。如果 TXMLParser 还使用一些非线程安全的全局变量,那么这段代码也不是线程安全的!不鼓励使用全局变量,但 Delphi 有相当多的内置变量,当它们被修改并从不同线程读取时可能会导致问题。
例如,
xmldom
单元有两个全局变量:DefaultDOMVendor
和DOMVendors
。这些并不经常修改,因此应该可以安全使用。SysUtils 单元还有一些全局变量,用于确定当前区域设置、日期/时间格式等。这些也不是线程安全的,尽管它们也几乎从未被修改过。
即使第三方代码也可能出于各种目的使用全局变量。一些更现代的代码甚至可能使用类变量,这也是一种全局变量,因此绝对不是线程安全,尽管风险取决于数据的次数已修改...
如果不查看 TXmlParser 的代码,就不清楚它是否是线程安全的。如果它使用像 Libxml2.dll 这样的第三方 DLL,那么它会变得更加复杂,因为该 DLL 的句柄可能存储在全局变量中,从而变得不安全。
话又说回来,你说 TXmlParser 是线程安全的。回答你的问题:只要“Do stuff”部分是线程安全的,你的代码也将是线程安全的。
Actually, it could be correct but doesn't have to be. If TXMLParser also uses some global variable that's not threadsafe, this code would not be threadsafe either! The use of global variables is discouraged but Delphi has quite a few build-in variables that might cause problems when they're modied and read from different threads.
The unit
xmldom
, for example, has two global variables:DefaultDOMVendor
andDOMVendors
. These aren't really modified often, thus should be safe to use.The SysUtils unit also has a few global variables used for determining the current locale, date/time formats and whatever more. Those aren't threadsafe either, although these too are almost never modified.
Even third-party code might use global variables for all kinds of purposes. Some more modern code might even use class variables which would also be a kind of global variables and thus definitely not threadsafe, although the risks are based on the number of times the data is modified...
Without a look in the code of TXmlParser it's unclear if it's threadsafe or not. If it uses a third-party DLL like Libxml2.dll then it becomes even more complicated since the handle for this DLL might be stored in a global variable, thus becoming unsafe.
Then again, you said TXmlParser is threadsafe. To answer your question: your code would then be threadsafe too as long as the "Do stuff" part is threadsafe.