这是一个很长的问题,但我们走了.有一个版本的FormatDateTime,据说是您使用的线程安全
GetLocaleFormatSettings(3081, FormatSettings);
得到一个值然后你可以像这样使用它;
FormatDateTime('yyyy', 0, FormatSettings);
现在想象两个计时器,一个使用TTimer(间隔说1000毫秒),然后另一个计时器创建如此(10毫秒间隔);
CreateTimerQueueTimer ( FQueueTimer, 0, TimerCallback, nil, 10, 10, WT_EXECUTEINTIMERTHREAD );
现在是一点点,如果在回调和计时器事件中你有以下代码;
for i := 1 to 10000 do begin FormatDateTime('yyyy', 0, FormatSettings); end;
请注意,没有任务.这会产生几乎立即访问的访问权限,有时甚至会在20分钟后随机出现.现在,如果您在C++ Builder中编写该代码,它永远不会崩溃.我们使用的标头转换是JEDI JwaXXXX.即使我们在代码中放入Delphi版本的锁,它也只会延迟不可避免的.我们已经查看了原始的C头文件,它看起来都很好,C++使用Delphi运行时有什么不同的方式吗?FormatDatTime的线程安全版本看起来是可重入的.任何可能以前看过这个的人的想法或想法.
更新:
为了缩小这一点,FormatSettings作为const传入,所以如果它们使用相同的副本(因为事实证明在函数调用中传递本地版本会产生同样的问题)是否重要?采用FormatSettings的FormatDateTime版本也不会调用GetThreadLocale,因为它已经具有FormatSettings结构中的Locale信息(我通过单步执行代码仔细检查).
我提到没有任何分配,以明确没有访问共享存储,因此不需要锁定.
WT_EXECUTEINTIMERTHREAD用于简化问题.我的印象是你应该只将它用于非常短的任务,因为它可能意味着如果它运行的时间很长,它会错过下一个间隔吗?
如果使用普通的旧TThread,则不会出现问题.我在这里得到的是我认为使用TThread或TTimer可以工作,但是使用在VCL外部创建的线程没有,这就是为什么我问C++ Builder使用VCL/Delphi RTL的方式是否存在差异.
顺便说一句,前面提到的代码也会失败(但需要更长时间),过了一会儿,CS:= TCriticalSection.Create;
CS.Acquire; for i := 1 to LoopCount do begin FormatDateTime('yyyy', 0, FormatSettings); end; CS.Release;
现在我真的不明白,我按照建议写了这个;
function ReturnAString: string; begin Result := 'Test'; UniqueString(Result); end;
然后在每种类型的计时器内部代码;
for i := 1 to 10000 do begin ReturnAString; end;
这会导致相同类型的故障,正如我之前所说,故障永远不会出现在CPU窗口内的同一位置等.有时它是一种访问冲突,有时它可能是一个无效的指针操作.我正在使用Delphi 2009 btw.
更新2:
Roddy(下面)指出了Ontimer事件(不幸的是还有Winsock,即TClientSocket)使用windows消息泵(除了使用IOCP和Overlapping IO有一些不错的Winsock2组件会很好),因此推动离开从中.但是,是否有人知道如何在CreateQueueTimerQueue上设置哪种线程本地存储?
感谢您抽出宝贵时间思考并回答这个问题.
我不确定在我自己的问题上发表"答案"是否是好的形式,但它似乎合乎逻辑,让我知道这是不是很酷.
我想我已经找到了问题,线程本地存储的想法引导我跟随一堆线索,我发现了这条神奇的线条;
IsMultiThread:= True;
从帮助;
"IsMultiThread设置为true表示内存管理器应该支持多个线程.IllMultiThread由BeginThread和类工厂设置为true."
这当然不是通过使用TTimer使用单个主VCL线程来设置的,但是在使用TThread时会为您设置.如果我手动设置它,问题就会消失.
在C++ Builder中,我不使用TThread,但它使用以下代码显示;
if (IsMultiThread) { ShowMessage("IsMultiThread is True!"); }
就是它会自动为你设置.
我真的很高兴人民的意见,以便我能找到这一点,我希望它可以帮助其他人.