0

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

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

我很难弄清楚如何在每个线程上处理每个项目时报告它的状态。

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

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

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

任何帮助,将不胜感激。

谢谢你。

4

1 回答 1

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

请注意,由于您的问题在细节上非常简单(用于其中的语言),因此您绝对需要使解决方案适应您想要完成的任何事情。这仍然应该给你一个很好的起点。

于 2011-04-03T08:16:12.343 回答