2012-07-06 43 views
2

我正在使用一个简单的静态线程池,其中有4个线程,每个线程都有一个队列,用于处理字符串列表中的各个行。在每个线程完成其队列中的其中一个请求后,它会同步在父线程中处理的事件。我需要一个线程安全的字符串列表来防止这种情况下的死锁吗?

procedure TDecoderThread.DoComplete(const Line: Integer; const Text: String); 
begin 
    FLine:= Line; 
    FText:= Text; 
    Synchronize(SYNC_OnComplete); 
end; 

procedure TDecoderThread.SYNC_OnComplete; 
begin 
    if assigned(FOnComplete) then 
    FOnComplete(Self, FText, FLine); //Triggers event which is handled in parent thread 
end; 

在另一端,在他们的父线程,这些事件与此程序办理:

procedure TDecoder.ThreadComplete(Sender: TDecoderThread; const Text: String; 
    const Line: Integer); 
begin 
    FStrings[Line]:= Text; //Updates the original line in the list with the new text 
end; 

因为我有4个不同的这是通过调用DoComplete()它完成后,像这样做线程,每个线程可能会同时调用这个OnComplete()事件,我是否也必须担心线程保护这个FStrings: TStrings?写入这个字符串列表时,两个线程同时触发它们的OnComplete()事件是否会在其父线程中导致死锁?或者主线程是否足够聪明以等待其中一个完成之后才能处理另一个呢?

PS - 是的,这个小小的项目试图回答another previous question来自SO的其他人,这个回答有很大不同,但为了让自己更熟悉多线程,我继续这个例子无论如何项目。

+0

这里什么都不会触发*死锁*。死锁是当线程A正在等待线程B并且同时线程B正在等待线程A时。更可能的危险在于它可能是一个竞赛。事实上,使用每行一个线程解决问题是一个非常糟糕的主意。这将比单线程执行更差。你想要的是将整个文本分成n部分(n =处理器数量)。然后将每个部分传递给一个线程。所有线程完成后,重新组装。 – 2012-07-06 08:06:37

+0

@David,多线程项目并不是为了回答上一个问题,而是现在完全不同的测试。 – 2012-07-06 12:11:04

回答

4

由于OnComplete活动由Synchronize()触发,你不需要使用一个线程安全的锁周围的FStrings名单,因为对列表中的所有访问正在通过主线程委托,所以只有一个OnComplete事件处理程序实际上可以一次运行。如果您没有使用Synchronize(),如果正在添加/删除项目并因此重新分配列表内存,或者其他线程正在读取FStrings中的值,而线程仍在运行,则需要围绕FStrings锁定这样的锁。如果处理线程是唯一访问FStrings的线程,那么不存在并发访问单个项目的风险,因此不需要锁定。

+0

这正是我希望听到的:D谢谢! – 2012-07-06 01:12:26

相关问题