Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading TCriticalSection是否允许对变量进行多线程访问?_Multithreading_Delphi - Fatal编程技术网

Multithreading TCriticalSection是否允许对变量进行多线程访问?

Multithreading TCriticalSection是否允许对变量进行多线程访问?,multithreading,delphi,Multithreading,Delphi,我想同步线程以访问公共变量。 假设我有N个线程,每个线程都可以访问TSyncThreds类型变量的全局实例 我可以调用IncCount、DecCount方法吗?或者我会遇到并发线程访问同一个对象实例的问题 我只是同步访问FCcounter变量 type TSyncThreads = class public FCounterGuard: TCriticalSection; FCounter: integer; FSimpleEvent: TSimpleEvent

我想同步线程以访问公共变量。 假设我有N个线程,每个线程都可以访问TSyncThreds类型变量的全局实例

我可以调用IncCount、DecCount方法吗?或者我会遇到并发线程访问同一个对象实例的问题

我只是同步访问FCcounter变量

type
  TSyncThreads = class

  public
    FCounterGuard: TCriticalSection;
    FCounter: integer;
    FSimpleEvent: TSimpleEvent;

    constructor Create();
    procedure Wait();
    procedure IncCounter();
    procedure DecCounter();
  end;


var
  SyncThread: TSyncThreads;

implementation
uses
  Math, Windows, Dialogs;



{ TSyncThreads }

procedure TSyncThreads.DecCounter;
begin
  FCounterGuard.Acquire;
  Dec(FCounter);
  if FCounter = 0 then
    FSimpleEvent.SetEvent;
  FCounterGuard.Release;
end;

procedure TSyncThreads.IncCounter;
begin
  FCounterGuard.Acquire;
  Inc(FCounter);
  FCounterGuard.Release;
end;

constructor TSyncThreads.Create();
begin
  FCounter := 0;
  FSimpleEvent := TSimpleEvent.Create;
  FCounterGuard := TCriticalSection.Create;
  FSimpleEvent.ResetEvent;
end;

procedure TSyncThreads.Wait;
var
  ret: TWaitResult;
begin
  ret := FSimpleEvent.WaitFor(INFINITE);
end;

是的,您的代码很好,如果对手头的任务有点过火的话。您担心多个线程访问同一个对象,但这正是像TCriticalSection和TEvent这样的同步对象的设计目的。想象一下,如果不能同时访问这些类,它们将是多么毫无意义

你不需要一个关键部分来保护你的柜台。您可以使用InterlockedIncrement和InterlockedIncrement进行更轻量级的访问。它们返回变量的前一个值,因此如果InterlocatedDecrement返回1,则您知道是时候设置事件了


如果计数器上有一个上限,那么您甚至可以避免所有这些代码,而是使用信号量。或者,您可以为每个线程设置自己的事件,然后使用WaitForMultipleObjects等待所有事件;一旦所有线程都设置了它们的事件,它就会返回,因此您不必同步对任何共享变量的访问。

谢谢!我喜欢联锁解决方案。注意-要使用联锁*功能,计数器的地址必须能被4整除。或者,使用我的TGp4AlignedInt记录,该记录提供了联锁函数和其他一些函数,可在处使用。整数变量唯一不能正确对齐的时间是它是否是压缩记录的成员。全局、局部、参数和类字段始终对齐。或者,如果出于任何原因使用$A1或$A2编译,则应使用try/finally块包装对acqure/Release的调用,以确保在保留关键部分时出现问题时调用Release。否则它永远不会被释放,keepen阻止了任何等待获取的东西。