【发布时间】:2012-03-19 20:57:24
【问题描述】:
我正在编写多线程应用程序。我有两个线程。 On 用于将一些数据从设备传输到全局数据缓冲区,其次用于将这些数据写入文件。
从设备到缓冲区的数据正在异步传输。第二个线程的目的应该是等待指定数量的数据写入主数据缓冲区,最后写入文件。
第一个线程在 DLL 中,第二个在主应用程序中。我暂时用事件来解决这个问题。第一个线程将数据从设备传输到主数据缓冲区并计算数据,当传输指定数量的数据时,它会设置一个事件。第二个等待事件发出信号,然后运行一些数据存储代码。很简单,因为它正在工作。
Thread1.Execute:
var DataCount, TransferedData: Integer;
DataCounter := 0;
while not Terminted do
begin
TransferData(@pData, TransferedData);
Inc(DataCounter, TransferedData)
if DataCounter >= DataCountToNotify then SetEvent(hDataCount);
end;
Thread2.Execute:
hndlArr[0] := hDataCount;
hndlArr[1] := hTerminateEvent;
while (not Terminated) do
begin
wRes := WaitForMultipleObjects(HandlesCount, Addr(hndlArr), false, 60000);
case wRes of
WAIT_OBJECT_0:
begin
Synchronize(WriteBuffer); // call it from main thread
ResetEvent(hndlArr[0]);
end;
WAIT_OBJECT_0 + 1:
begin
ResetEvent(hTerminateEvent);
break;
end;
WAIT_TIMEOUT: Break;
end;
end;
现在我想让第二个线程更加独立......所以我可以创建第二个线程的多个实例,而我不需要等待第一个线程。我想将代码的数据计数部分从第一个线程移动到第二个线程,这样我就不再需要在第一个线程中进行数据计数了。第一个将仅用于数据传输目的。
我想使用第二个作为数据计数器并存储数据。但现在我将不得不循环并不断手动检查指定的数据量。如果我有while循环,我将不得不添加一些睡眠,所以第二个线程不会降低计算机性能,但我不知道睡眠应该多长时间,而第一个线程中的数据传输速度不是恒定的,因此第二个线程中的计数速度会有所不同。
我猜这个代码示例不好:
Thread2.Execute:
var DataCount: Integer;
DataIdx1 := GetCurrentDataIdx;
while (not Terminated) do
begin
if (GetCurrentDataIdx - DataIdx1) >= DataCountToNotify then
begin
Synchronize(WriteBuffer);
DataIdx1 := GetCurrentIdx;
end;
sleep(???);
end;
所以我的问题是解决数据计数问题并将其存储在第二个线程中的最佳方法是什么?您有什么经验和建议?
【问题讨论】:
-
为什么要强制将文件写入主线程
Synchronize(WriteBuffer)?我不明白你将如何设法增加第二个线程并仍然保持对单个文件的写入顺序。 -
线程将成倍增加,但数据将存储到不同的文件中。我无处写我要把它写到同一个文件中。我的目标是拥有多个控件,它们能够将来自同一源的数据存储到不同的文件中。
-
很高兴知道,因为答案将取决于此信息。我仍然想知道为什么必须将文件写入强制执行到主线程。
-
@Nix - 好好听 LU RD。文件系统是 100% 线程安全的,不需要同步。
-
Nix,第一个线程如何知道如何将数据分发给接收线程?通常这样的生产者线程只是组装数据并将其放入队列中。然后根据需要尽可能多的消费者线程可以处理队列的耗尽。
标签: multithreading delphi thread-safety delphi-2010