我该如何使用关键部分?

时间:2016-01-21 11:16:03

标签: multithreading delphi

我有问题应该放置CriticalSection。在线程中我有公共过程(写),我在文件中写入数据。

当我调用此过程时,我应该在此过程中还是在每个线程中使用CriticalSection?

示例:

我有一个帖子,我创建了CS。

type
  TMyThread = class(TThread)
  private
    { Private declarations }
  CS:TCriticalSection;
  public
    procedure Write(msg:string);
  protected
    procedure Execute; override;
    constructor Create;
  end;


constructor TMyThread.Create;
begin
CS.TCriticalSection.Create;
end;

我的问题。哪里用CS?

有:

procedure TMyThread.Write(msg:string);
begin
  CS.Enter;
  { WRITING IN FILE msg }
  CS.Leave;
end;

还是在每个帖子中?

CS.Enter;
MyThread.Write('cos');
CS.Leave;

2 个答案:

答案 0 :(得分:4)

这个答案是在假设每个线程写入单个公共文件的情况下编写的。因此需要同步。如果您在评论中亲密,每个线程写入不同的文件,则不需要同步。

您的代码存在很多问题。您需要在关键部分的实例和受保护对象之间进行一对一映射。在这里,每个线程有一个关键部分,完全没有用处。您的代码不会执行序列化。

由于您要保护对单个文件的访问权限,因此您需要拥有关键部分对象的单个实例。每个线程必须能够访问该单个共享临界区对象。一些选择:

  1. 将关键部分对象传递给线程,并安排线程的使用者管理关键部分对象的生命周期。
  2. 在声明线程的单元的实现部分中将临界区对象声明为全局变量。在单元的初始化和完成部分中创建和销毁对象。
  3. 将关键节对象声明为线程中的类变量。在类构造函数和类析构函数中创建和销毁对象。
  4. 将关键部分和日志写入专用日志记录类。
  5. 除此之外,你的线程的构造函数被破坏了。您必须调用继承的构造函数才能正确创建线程对象。

    鉴于所有这些更改,您建议使用临界区的任一选项都将正常运行。但是,获取Write内的锁定显然要好得多。这样就无法在不获取锁定的情况下调用该函数。获取锁的代码只需写一次。

答案 1 :(得分:3)

如果要从多个线程写入单个文件,则应该在所有这些线程中共享相同的关键部分,这意味着您通常应该在其他地方创建一个关键部分实例并在线程构造函数中传递它,示例

Text to display if no picture available
相关问题