multithreading - Delphi线程锁等待字符串操作

标签 multithreading delphi wait locks

有一个简单的代码:

  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/

相关文章:

java - 使用 JDBC 和 c3p0 在 MySQL DB 上进行多线程写入

java - Android Activity会关闭Looper&Handler吗?

delphi - 无法在 Delphi XE2 应用程序中显示 .chm 帮助文件 - 为什么?

regex - 在带有 rawbytestring 的 Delphi Xe 中使用正则表达式

c - wait() & 在 parent 循环 linux

c++ - std::lock_guard 似乎提供了线程安全性,尽管有作用域 block

c++ - 如何在写入其他 std::atomic 之后强制读取 std::atomic?

delphi - 如何停止在 Delphi 10 Seattle IDE 中创建 .stat 文件

jQuery:WAITING多个 GET 请求成功处理

python - 执行并等待结果 C 程序和 Python 脚本