- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我读到,如果克隆是只读的(不发布记录或重新加载数据),则克隆的 TClientDataSet 是线程安全的
Delphi - Is TClientDataset Thread Safe?
但我担心 CloneCursor 方法本身;该方法最后调用源 DataSet 的 SetNotifyCallback 方法,如果 FNotifyCallback 为 False,该方法会将回调方法传递给它的 IDSCursor:
procedure TCustomClientDataSet.SetNotifyCallback;
begin
if not FNotifyCallback then
begin
Check(FDSCursor.SetNotifyCallBack(IntPtr(Self), @TCustomClientDataSet.NotifyCallback));
FNotifyCallback := True;
end;
end;
在不太可能发生的情况下,两个数据集 A 和 B 在几乎同时克隆到数据集 C 的单独线程中(数据集 C 的 FNotifyCallback False),其中 A 稍微领先于 B。在 A 检查后,B 开始执行 C 的 SetNotifyCallBack FNotifyCallback 但在 A 在上面所示的方法中将 FNotifyCallBack 设置为 True 之前。
在这种情况下,DataSet C 的 FDSCursor SetNotifyCallback 方法几乎同时被两个不同的线程调用;一种在 IDSCursor 中编写对变量的引用的方法(我认为;找不到源代码)。诚然,两个调用都要求存储相同的引用,但正如标题所问,CloneCursor 线程安全吗?
请提前接受我的谢意。
最佳答案
问题中提出的问题围绕着两个线程 A 和 B 同时克隆到 C 的尽管不太可能发生的事件,这些事件代表自 C 打开以来对 C 的 CloneCursor 方法的第一次调用(FNotifyCallback False)。这导致C的IDCursor SetNotifyCallback有可能同时被两个单独的线程调用。
根据 Graymatter 的评论,一种解决方案是确保对 C 的 CloneCursor 的第一次调用发生在 C 的线程内。完成此操作后,FNotifyCallback 为 True,并且只要 C 保持打开状态,FNotifyCallback 就保持不变。
如果 FNotifyCallback True,C 语言的 SetNotifyCallback 代码将解析为以下指令(在我的 PC 上):
006418CB cmp byte ptr [ebx+$00000290],$00
006418D2 jnz $006418fa
{code to call IDSCursor SetNotifycallback}
006418FA 5B pop ebx
006418FB C3 ret
如果 FNotifyCallback 为 True,SetNotifyCallback 会简化为在跳转到 pop 和 ret 指令之前将 FNotifyCallback 的内容与值零进行比较。
冒着被打的风险,我相信一旦FNotifyCallback为True,那么后续调用SetNotifyCallback就是线程安全的。
虽然问题的主体集中在 SetNotifyCallback 上,但该问题专门针对 CloneCursor。唯一值得关注的其他领域(我可以看到)围绕克隆数据集的 FDSBase 到源(本讨论中的 C)FDSBase 的分配。这将增加源 FDSBase 接口(interface)的引用计数。
在我的电脑上,这解析为一条指令来增加内存位置:
inc dword ptr [eax+$04]
我假设这是原子的。另外,我无法相信,使接口(interface)的引用计数线程安全的递增和递减并不是接口(interface)首次提出时首先考虑的事情之一。
总之,我相信一旦 FNotifyCallback 为 True,CloneCursor 就是线程安全的。
关于multithreading - TCustomClientDataSet CloneCursor 线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32261215/
我有一个连接到 Firebird 数据库的 DB Express TSimpleDataset。我刚刚向数据集添加了数千行数据,现在是时候调用 ApplyUpdates 了。 不幸的是,当它尝试单独插
我读到,如果克隆是只读的(不发布记录或重新加载数据),则克隆的 TClientDataSet 是线程安全的 Delphi - Is TClientDataset Thread Safe? 但我担心 C
我是一名优秀的程序员,十分优秀!