У меня есть простая реализация пула потоков, используя boost::function
, а также boost::bind
уменьшить сигнатуру функции-члена до void func(void)
, Это затем использует очередь boost::function
а также int
пар, выскакивает из верхней части очереди и выполняет функцию (все обернуто в блок мьютекса).
threadPool->addJob(boost::bind(&Foo::bar, this, arg1, arg2));
...
typedef boost::function<void(void)> func;
std::queue<std::pair<func, int> > funcQ;
void ThreadPool::addJob(func f){
funcQ.push(std::make_pair(f, j));
}
if (!funcQ.empty()){
func localFunc = (funcQ.front()).first;
...
funcQ.pop();
...
localFunc();
}
Однако после нескольких итераций это вызывало ошибку, когда я вызывал ()
оператор в функции, поэтому я бросил в операторе assert, чтобы убедиться, что функция вызывается:
...
assert(funcQ.front().first);
func localFunc = (funcQ.front()).first;
...
И вот, после нескольких итераций, утверждения утверждают, что мой boost::function
не был вызван.
Сначала я подумал, что, возможно, данные функции (из Foo
класс) был уничтожен до вызова функции, однако, насколько я понимаю, boost::function
создает копию данных для формирования закрытия в любом случае. К сожалению, я не знаю достаточно о причинах boost::function
s быть недействительным для дальнейшего развития проблемы. Я неправильно привязываю функцию-член, или проблема лежит где-то посередине и пытаюсь вызвать ее?
Изменить: я должен был упомянуть: Foo
размещается в куче, а не delete
d, пока потоки не соединятся.
std :: queue не является потокобезопасным. Когда вы говорите, что используете мьютекс для выхода из очереди, я понимаю, что вы будете делать то же самое для добавления в очередь.
Также вам необходимо позаботиться о жизни Foo. Подумайте о передаче shared_ptr асинхронным функциям. (shared_from_this () вместо этого)
Примечание. Вы можете использовать boost :: asio для планирования задач.
Вот очень хорошая статья об этом
http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio/
Других решений пока нет …