我有一些基于TThreads的操作。现在我需要创建包含要完成的作业列表的线程,然后在前一个完成后立即触发每个...我应该如何编写它?我不能允许线程同时运行,因为可能有超过10 000个操作要完成。 很难找到TEvent和其他同步对象的文档示例...... 希望我能在这里找到一些帮助...
提前致谢, 米甲
答案 0 :(得分:5)
不要将操作建立在线程上。这是错误的设计。相反,您应该为您的操作创建一个基类,它公开了一个执行操作的方法。编写后代类来实现具体操作。不要对线程上下文做任何假设,总是使用关键部分或类似的同步对象来保护对共享资源的访问。更重要的是,尽量避免共享资源,或者至少尝试将共享资源设置为只读,这样就不需要锁定。
通过该设计,可以通过直接调用操作方法在VCL线程中执行每个操作,使用TThread
后代类在自己的线程中执行操作(您似乎拥有的操作) now),或安排线程池上的所有操作。可以在运行时调整池中的线程数,以匹配操作的性质(处理器绑定或I / O绑定)和系统具有的处理器核心数。并回答您的问题:甚至可以通过强制池使用单个线程来完全序列化操作。基本上,您可以完全改变操作的执行方式,而无需更改他们。
答案 1 :(得分:2)
我刚刚实现了非常类似的东西。
我认为你想要的是一个线程池系统。
您有一个包含一定数量线程的线程池(将同时执行的最大项目数)。然后,您创建一个工作单元对象,并放入队列中。每个工作线程获取第一个可用的排队工作单元并执行它。完成后,工作线程将等待,直到队列中有更多工作单元。
这种方法的优点是您可以轻松控制最大数量的同时操作,并且不会为每个操作创建和丢弃线程(这很昂贵)。
答案 2 :(得分:2)
你应该看看OmniThreadLibrary。它使工作线程非常简单,你基本上只是为它添加一个任务;每一个都在上一个完成之后立即启动,并且库允许您轻松地将状态消息等传递回主线程以进行UI更新。
答案 3 :(得分:1)
假设您有一个执行其他线程的线程,比如WorkerThread。
在WorkerThread中,您可以将要调用的线程放在TThread,TThreadList,TList的数组中,基本上哪个更适合您。
然后在for循环中启动它们中的每一个。现在,既然你不希望它们同时运行你有2种方法等待正在运行的线程,要么使用一些标志并听取线程的OnTerminate事件,当被触发时设置标志,或者使用
WaitForSingleObject(Thread.Handle, INFINITE);
答案 4 :(得分:0)
我不完全理解你的问题,并没有真正理解使用多个线程然后序列化执行...但你可以这样做:
JobList : TList <TThread>;
...
JobList.Add (TMyCustomThread.Create (True)); // Create suspended
JobList.Add (TMyOtherThread.Create (True)); // Create suspended
...
for Thread in JobList do
begin
Thread.Start;
Thread.WaitFor;
end;
这将执行每个线程,然后等到线程完成后再执行下一个线程。
示例代码假定您使用D2009或更高版本(您未在问题中指定)并且已创建线程处于挂起状态。如果您使用较旧的Delphi版本,则必须调用Resume
而不是Start
,并且必须使用简单的TList
或数组替换通用TList
。
请注意示例代码中的内存泄漏。
答案 5 :(得分:0)
泛型集合TQueue可以用作单个作业对象的容器。
然后工作线程将接收('提取')第一个作业并执行它,然后继续直到队列为空 - 然后它必须暂停,直到另一个作业被添加到队列并继续。 / p>
您需要实现对队列的线程安全访问以添加新作业。