有一个简单的代码:
TParallel.For(1, 8,
procedure(i: Integer)
var
localstr: String;
Data: String;
index: Integer;
begin
Data := 'test1 test2';
index := 0;
while true do
begin
index := index + 1;
localstr := copy(Data, index, 1);
if index > 2 then
index := 0;
end;
end);
它应该使用 8 个 CPU 核心,但它只使用 1 个。原因是清除 string
变量的系统过程:
function _UStrClr(var S): Pointer;
if AtomicDecrement(P.refCnt) = 0 then
FreeMem(P);
AtomicDecrement()
应用锁来确保字符串
的引用计数不会在不同线程上同时递减。但是,我绝对确定我的字符串在线程内是隔离的。有什么方法可以告诉 TParallel
不要这样做吗?
我可以使用经典的低级 WinAPI 调用,但这会丢失旧代码库。
最佳答案
It should use 8 CPU cores
仅仅因为您正在创建 8 个并行循环迭代,并不能保证每个迭代都将在其自己的 CPU 内核上运行。有些完全有可能在同一个 CPU 核心上运行,操作系统必须在它们之间进行任务切换。任务运行在哪个 CPU 核心上取决于操作系统的线程调度程序。
But, I am absolutely sure that my strings are isolated inside the threads.
您对字符串的使用是隔离的,但编译器/RTL 对字符串的使用不是隔离的。底层内存管理是相当线程安全的,这意味着同步对字符串内部结构的访问,以防多个线程尝试同时访问给定字符串。
Is there any way to tell
TParallel
not to do that?
不,这本来就不是 TParallel
的错。这就是 RTL 对字符串的内部管理的一般实现方式。如果您不喜欢它,请不要首先使用引用计数的字符串
。
关于multithreading - Delphi线程锁等待字符串操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75666893/