C: Как создать пул с pthreads?

У меня очередь заданий, и я хочу создать пул из 4 потоков, где я могу бросить свои задания. Я застрял в том, как создавать потоки и держать их подвешенными, пока нет работы.

JOB QUEUE        | job1 | job2 | job3 | job4 | ..

THREAD POOL      | thread1 | thread2 | thread3 | thread4 |

Чтобы создать потоки, которые я имею в настоящее время в точке инициализации:

for (t=0; t<num_of_threads; t++){
    pthread_create(&(threads[t]), NULL, doSth2, NULL);
}

Где num_of_threads = 4 и doSth2 - это функция, в которой нет ничего. Итак, как только я создал 4 потока, и они сделаны с doSth2, как я могу дать им новую работу, не убивая их?

Ответ 1

Ключ к пулу потоков - это очередь. Вот измененные функции для пула потоков, которые я разработал.

Поместить элемент в очередь

void queue_add(queue q, void *value)
{
    pthread_mutex_lock(&q->mtx);

    /* Add element normally. */

    pthread_mutex_unlock(&q->mtx);

    /* Signal waiting threads. */
    pthread_cond_signal(&q->cond);
}

Получить элемент из очереди

void queue_get(queue q, void **val_r)
{
    pthread_mutex_lock(&q->mtx);

    /* Wait for element to become available. */
    while (empty(q))
        rc = pthread_cond_wait(&q->cond, &q->mtx);

    /* We have an element. Pop it normally and return it in val_r. */

    pthread_mutex_unlock(&q->mtx);
}

Ответ 2

Как альтернативный рифф на ответ cnicutar, вы можете просто использовать очереди сообщений POSIX, которые позаботятся о проблемах синхронизации в ядре. Для системных вызовов будут небольшие накладные расходы, которые могут быть или не быть проблемой. Это довольно минимально, поскольку ядро ​​делает все, что вам нужно было бы сделать вручную в любом случае.

Потребительские потоки могут просто блокироваться на mq_receive, и если вы создаете сообщение о специальном типе очереди, это позволяет легко сообщать потоки при закрытии.