跟踪不同线程上对象实例的状态?

时间:2011-04-03 01:16:03

标签: multithreading events status consumer producer

我在空闲时间写一个图像板刮刀,主要教我线程化。目前我正在使用生产者/消费者类型模式来促进这项工作。但是,我遇到了一个问题。

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

我很难确定在每个线程上处理每个项目时如何报告每个项目的状态。

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

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

我尝试使用事件报告状态,但我遇到了一些不稳定的结果。我用谷歌搜索了一些关于使用线程和事件的信息,但是并没有走得太远。

任何帮助都将不胜感激。

谢谢。

1 个答案:

答案 0 :(得分:1)

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

一旦你完成了这个,你就会遇到另一个问题:谁会轮询队列?您可以使用主线程在其对作业队列的检查之间执行此操作,但这可能很难看,并且可能会不必要地减慢处理速度。你也可以产生另一个线程来做这个,但我猜你需要将状态报告给主线程,所以这没有帮助。

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

这里有一些伪代码来说明这个概念:

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()来删除作业线程,但根据您使用的语言或库,它可能不是最明智的方法。如果您的语言支持这种事情,那么在do_job(job)语句中包围try catch调用可能也是个好主意。

请注意,由于您的问题在细节上非常明显(用于一个语言),您肯定需要使解决方案适应您想要完成的任何事情。这应该仍然是一个很好的起点。