Multithreading 我应该如何使用临界截面?
我不知道应该把CriticalSection放在哪里。在线程中,我有一个公共过程(write),在这个过程中我将数据写入文件 调用此过程时,我应该在该过程中使用CriticalSection还是在每个线程中使用CriticalSection 例如: 我有一个线程,我创建了CSMultithreading 我应该如何使用临界截面?,multithreading,delphi,Multithreading,Delphi,我不知道应该把CriticalSection放在哪里。在线程中,我有一个公共过程(write),在这个过程中我将数据写入文件 调用此过程时,我应该在该过程中使用CriticalSection还是在每个线程中使用CriticalSection 例如: 我有一个线程,我创建了CS type TMyThread = class(TThread) private { Private declarations } CS:TCriticalSection; public pr
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;
这个答案是在假设每个线程都写入一个公共文件的基础上编写的。因此需要同步。如果,正如您在评论中提到的,每个线程都写入不同的文件,那么就不需要同步
您的代码有很多问题。您需要在关键部分的实例和受保护对象之间进行一对一映射。在这里,每个线程有一个关键部分,根本没有任何用途。您的代码不会执行任何序列化 由于您要保护对单个文件的访问,因此需要具有critical section对象的单个实例。每个线程都必须能够访问单个共享的临界截面对象。一些选择:
考虑到所有这些更改,您建议的使用关键部分的任何选项都将正常工作。但是,在
Write
中获取锁显然要好得多。这样,在不获取锁的情况下调用函数是不可能的。获取锁的代码只需编写一次。如果要从多个线程写入单个文件,则应在所有这些线程之间共享同一个临界段,这意味着您通常应在其他位置创建临界段实例,并将其传递给线程构造函数,例如
type
TMyThread = class(TThread)
private
{ Private declarations }
FCS:TCriticalSection;
public
procedure Write(msg:string);
protected
procedure Execute; override;
constructor Create(ACS: TCriticalSection);
end;
constructor TMyThread.Create(ACS: TCriticalSection);
begin
inherited Create; // don't forget to call inherited constructor
FCS:= ACS;
end;
procedure TMyThread.Write(msg:string);
begin
FCS.Enter;
{ WRITING IN FILE msg }
FCS.Leave;
end;
所以我只能在我写的这个过程中使用CS,任何其他线程都可以使用这个过程,一切都会好起来吗?我这样问是因为其他线程不会看到这个CS。其他线程确实看到了它。线程执行代码,当这些线程调用函数时,它们可以看到该部分。@MBo你是对的,代码还有许多其他问题。我没有仔细研究它。我会更新的,所以。。。我可以创建全局数组并为每个线程放置每个CS吗?不可以。假设每个线程都写入同一个文件,那么每个线程都需要恰好共享一个关键部分。如果每个线程都写入不同的文件,那么根本不需要同步;关键部分同步不同的线程实例,不清楚您将如何使用关键部分。所以我问如何使用关键部分:)您甚至使用谷歌了吗?重要的是要理解关键部分是为了保护数据(而不是代码)。您需要清楚地了解代码在做什么,以便知道多个线程何时可能访问共享数据。(数据可以在内存中,也可以在文件中;两种方式的主体都是相同的。)如果相同的代码总是从不同的线程访问不同的对象,则不需要关键部分。如果不同的代码从单个线程访问相同的对象,您仍然不需要关键部分。您只需要为使用相同对象/数据的多个线程使用它们。当您确实需要关键部分时,每个需要保护的对象必须由单个关键部分保护(否则根本没有保护)。此外,在开始使用来自任何可以访问数据的地方的数据之前,您需要确保输入关键数据。然而,在这一点上,理解保护数据和代码之间的区别是很重要的。您可以在实际接触数据的方法内部本地化输入critical,因为
CS.Enter
只是代码!这非常重要,避免了大量的重复代码。如果每个线程都有自己的文件和其他线程,除了在他的文件中写入之外,还想在其他“线程文件”中写入吗?这就是我想要实现的,您需要一种机制来为每个线程中的每个文件选择正确的关键部分。(如果我理解正确的话)可能是synchronize
比TCriticalSection