Чтобы мои потоки не выполнялись в пустоте, когда им нечего делать, я блокирую их с помощью 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();
}
}
Вот пример:
Код: Выделить всё
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