Pthread_cond_broadcast не пробуждает потоки, ожидающие с помощью pthread_cond_waitC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Pthread_cond_broadcast не пробуждает потоки, ожидающие с помощью pthread_cond_wait

Сообщение Anonymous »

У меня возникла проблема с моими тредами. Я пишу программу, которая должна выполнять асинхронные задачи, и делаю это через пул потоков.
Чтобы мои потоки не выполнялись в пустоте, когда им нечего делать, я блокирую их с помощью pthread_cond_wait, затем, когда приходит новая задача, я разбудил ее с помощью pthread_cond_signal.
Я указываю, что обязан использовать C++98, поэтому я нет доступа в библиотеку std::thread, поэтому я использую функции C.
В MacOS все работает отлично, и на данный момент я не обнаружил никаких проблем.
В MacOS все работает отлично, и на данный момент я не обнаружил никаких проблем.
p>
Вот мой класс ThreadPool:

Код: Выделить всё

#include 
#include 
#include
#include 
#include 

class ThreadPool {
public:
ThreadPool(size_t numThreads);
~ThreadPool();

void    enqueueTask(void (*function)(int, int), int client_fd, int backend_fd);

void    kill();

private:
std::vector workers;
std::queue tasks;
std::queue taskArgs;

pthread_mutex_t queueMutex;
pthread_cond_t condition;
bool stop;

static void* workerThread(void* arg);
void run();
};
А вот моя реализация:

Код: Выделить всё

ThreadPool::ThreadPool(size_t numThreads): stop(false)
{
pthread_mutex_init(&queueMutex, NULL);
pthread_cond_init(&condition, NULL);

for (size_t i = 0; i < numThreads; ++i) {
pthread_t worker;
pthread_create(&worker, NULL, workerThread, this);
workers.push_back(worker);
}
}

ThreadPool::~ThreadPool()
{
if (!stop) {
this->kill();
}
}

void    ThreadPool::kill()
{
pthread_mutex_lock(&queueMutex);
stop = true;
pthread_cond_broadcast(&condition);
pthread_mutex_unlock(&queueMutex);

for (size_t i = 0; i < workers.size(); ++i) {
pthread_cancel(workers[i]);
}

for (size_t i = 0; i < workers.size(); ++i) {
pthread_join(workers[i], NULL);
}

pthread_mutex_destroy(&queueMutex);
pthread_cond_destroy(&condition);
}

void    ThreadPool::enqueueTask(void (*function)(int, int), int client_fd, int backend_fd)
{
pthread_mutex_lock(&queueMutex);
tasks.push(function);
taskArgs.push(std::make_pair(client_fd, backend_fd));
pthread_cond_signal(&condition);
pthread_mutex_unlock(&queueMutex);
}

void    *ThreadPool::workerThread(void* arg)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

ThreadPool* pool = (ThreadPool*)arg;
pool->run();
return NULL;
}

void    ThreadPool::run()
{
while (true) {
pthread_mutex_lock(&queueMutex);

while (!stop && tasks.empty()) {
pthread_cond_wait(&condition, &queueMutex);
}

if (stop) {
pthread_mutex_unlock(&queueMutex);
return;
}

void (*task)(int, int) = tasks.front();
std::pair args = taskArgs.front();
tasks.pop();
taskArgs.pop();

pthread_mutex_unlock(&queueMutex);

pthread_testcancel();

task(args.first, args.second);

pthread_testcancel();
}
}
Моя проблема заключается в следующем: в Linux (по крайней мере, Ubuntu) когда я вызываю свою функцию ThreadPool::kill(), чтобы остановить все потоки, pthread_cond_broadcast делает не разбудить потоки, и они останутся заблокированными при pthread_cond_wait, заставляя основной поток ждать их присоединения к ним с помощью pthread_join, полностью блокируя программу, и единственный способ остановить ее - отправить SIGKILL для процесса.
Вот пример:

Код: Выделить всё

bool running = true;

static void interruptHandler(int sig_int) {
(void)sig_int;
running = false;
}

void task(int a, int b)
{
size_t i = a + b;
size_t r = 0;

for (; i < 1000000; i++)
r = a + i;
sleep(1);
std::cout kill();
}
Проблема та же.
Я не понимаю, почему в Linux такое поведение и как с этим бороться и решить проблему блокировки.
Проблема та же самая.
Я не понимаю, почему в Linux такое поведение и как с этим бороться и решить проблему блокировки.
Проблема та же.
Я не понимаю, почему в Linux такое поведение и как с этим бороться и решить проблему блокировки.
Проблема та же.
Я не понимаю, почему в Linux такое поведение и как с этим бороться и решить проблему блокировки.
Проблема та же.
Я не понимаю, почему в Linux такое поведение и как с этим бороться.
p>
Спасибо за помощь.

Подробнее здесь: https://stackoverflow.com/questions/791 ... -cond-wait
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»