Один из способов сделать это - создать другую потокобезопасную очередь, которая будет использоваться для сообщения об обновлениях состояния.Каждый раз, когда ваш поток меняет свой статус, он выдвигает кортеж / объект, содержащий уникальный идентификатор работы, новый статус, идентификатор потока и все, что вы считаете необходимым.
Как только вы это сделаете,Вы столкнетесь с другой проблемой: кто будет опрашивать очередь?Вы можете сделать это с вашим основным потоком между его проверками в очереди заданий, но это может быть уродливо и может излишне замедлить обработку.Вы также можете создать другой поток для этого, но я предполагаю, что вам нужно сообщить о статусе главному потоку, чтобы это не помогло.
На самом деле есть лучший способ структурировать программу.Вместо того, чтобы основной поток постоянно опрашивал очередь заданий и создавал потоки (что довольно дорого), вы могли бы вместо этого создать пул потоков и позволить потокам заданий выполнять опрос самостоятельно.Это оставит основной поток свободным для опроса очереди состояния в ожидании любого события, которое он ищет.
Вот некоторый псевдокод, иллюстрирующий концепцию:
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});
По сути, это создает пул потоков, который содержит один рабочий поток на каждое ядро процессора (нормально по умолчанию для запускас).Затем он выполняет функцию worker_thread
в каждом рабочем потоке (функция должна быть понятной).Затем основной поток постоянно проверяет очередь состояния на наличие определенного неопределенного события.Как только это происходит, он убивает рабочие потоки и возобновляет выполнение остальной части программы.
Три вещи, на которые стоит обратить внимание в примере.Прежде всего, я рекомендую использовать блокирующий всплывающий вызов (pop_blocking
в примере) вместо реализации опроса вручную.Это намного проще в использовании и, возможно, гораздо эффективнее.Затем я использовал thread_pool.interrupt()
, чтобы уничтожить потоки заданий, но это может быть не самый умный способ сделать это в зависимости от языка или библиотеки, которую вы используете.Возможно, это также хорошая идея заключить вызов do_job(job)
в оператор try catch
, если ваш язык поддерживает такие вещи.
Обратите внимание, что поскольку ваш вопрос довольно легок в деталях (язык, используемый для1) вам определенно нужно будет адаптировать решение к тому, что вы пытаетесь достичь.Это все равно должно дать вам хорошую отправную точку.