2011-04-03 50 views
0

我在空闲时间写了一个图像板刮板来教我主要关于线程。目前我正在使用生产者/消费者类型模式来促进这项工作。但是,我遇到了一个问题。跟踪不同线程上对象实例的状态?

现在,我有“队列处理器”,观察并处理特定类型的线程安全队列。这些队列处理器每隔X秒轮询一次目标队列,并且如果队列中有等待处理的项目,队列处理器会使该项目出队,使用该项目旋转一个新线程并启动线程。在每个线程上,调用长时间运行的方法(如连接到网站并下载文件)。以这种方式,每个项目都有自己的线程运行。

我很难搞清楚如何报告每个线程正在处理的每个项目的状态。

例如,假设我们有主线程MT。 MT产生子线程T1,T2,T3,T4和T5。在每个线程上都有一个对应的对象,O1 ... O5。这些对象可以处于三种不同的状态(S1,S2,S3),而它们正在其线程上进行处理。

如何在对象O的状态发生变化时向主线程MT报告每个对象O的状态S?

我尝试使用事件来报告状态,但我遇到了一些令人毛骨悚然的结果。我搜索了一些关于使用线程和事件的信息,但没有得到太多的结果。

任何帮助,将不胜感激。

谢谢。

回答

1

一种方法是创建另一个线程安全队列,用于报告状态更新。每当你的线程改变它的状态时,它都会推送一个元组/对象,它包含作业的唯一标识符,新状态,线程标识以及你认为需要的任何其他内容。

一旦你这样做了,你会遇到另一个问题:谁来轮询队列?你可以在你的主线程在它对工作队列的检查之间做到这一点,但这可能很难看,并且可能会不必要地减慢处理速度。你也可以为此做出另一个线程,但我猜你需要将状态报告给主线程,所以这没有帮助。

实际上有更好的方法来构造程序。不是让主线程连续轮询作业队列并创建线程(这非常昂贵),而是可以创建一个线程池并让作业线程自己执行轮询。这将使主线程免费轮询状态队列,等待它正在查找的任何事件。

下面是一些伪代码来说明这一概念:

main_thread() 
    ... 
    thread_pool = create_pool(get_core_count()); 
    thread_pool.execute(worker_thread); 

    while(true) 
     status = status_queue.pop_blocking(); 
     if (check_status(status) == WE_BE_DONE) 
      break; 

    thread_pool.interrupt(); 
    ... 

worker_thread() 
    while(true) 
     job = job_queue.pop_blocking(); 
     process_job(job); 
     status_queue.push({job.id, thread_id, WE_DONE}); 

从本质上讲,这是什么做的是创建一个包含每个你有CPU核心一个工作线程(一个确定的默认开始)线程池。接下来,它在每个工作线程中执行函数worker_thread(该函数应该是不言自明的)。主线程然后不断地检查状态队列以查找某个未指定的事件。一旦发生这种情况,它会关闭工作线程并继续执行程序的其余部分。

这个例子值得注意的三件事。首先,我建议在手动轮询实施中使用屏蔽流行呼叫(示例中为pop_blocking)。使用起来要简单很多,效率可能更高。接下来,我使用thread_pool.interrupt()来终止工作线程,但根据您使用的语言或库,它可能不是最聪明的方法。如果您的语言支持这种事情,那么在try catch声明中围绕do_job(job)调用可能也是一个好主意。

请注意,由于您的问题对于细节(语言被用于某个细节)非常不利,因此您肯定需要将解决方案适应于您正在尝试完成的任何操作。这应该仍然给你一个很好的起点。