Delphi 线程锁等待字符串操作

e4eetjau  于 2023-03-12  发布在  其他
关注(0)|答案(1)|浏览(140)

有一个简单的代码:

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变量的系统过程:
x一个一个一个一个x一个一个二个x
AtomicDecrement()应用了一个锁来确保string的引用计数不会在不同的线程上同时递减。但是,我绝对肯定我的string在线程内部是隔离的。有什么方法可以告诉TParallel不要这样做吗?
我可以使用经典的低级WinAPI调用,但这会丢失遗留代码库。

inb24sb2

inb24sb21#

它应该使用8个CPU核心
仅仅因为你创建了8个并行循环迭代并不能保证每个迭代都在自己的CPU核心上运行。完全有可能一些迭代会在同一个CPU核心上运行,操作系统必须在它们之间进行任务切换。任务在哪个CPU核心上运行取决于操作系统的线程调度器。
但是,我绝对肯定我的字符串是孤立在线程内部的。

  • 你 * 对字符串的使用是独立的,但编译器/RTL对字符串的使用不是。底层的内存管理是相当线程安全的,这意味着同步访问字符串的内部结构,* 以防 * 多个线程试图同时访问给定的字符串。

有什么办法可以告诉TParallel不要这么做吗?
不,这不是TParallel的错。这只是RTL内部管理string s的一般实现方式。如果你不喜欢它,不要使用引用计数的string s作为开始。

相关问题