一种方法是创建另一个线程安全队列,用于报告状态更新。每次您的线程更改其状态时,它都会推送一个元组/对象,其中包含作业的唯一标识符、新状态、线程 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
请注意,由于您的问题在细节上非常简单(用于其中的语言),因此您绝对需要使解决方案适应您想要完成的任何事情。这仍然应该给你一个很好的起点。