boost :: thread_group在线程完成后永远悬挂

boost::thread_group hangs forever after threads complete

本文关键字:永远 线程 thread group boost      更新时间:2023-10-16

我有一个简单的程序,该程序计算n(并最小化p)的lemoine,对于范围内的所有n。我正在尝试使用boost :: thread_group使用指定数量的核心来养活工作。这是我的代码:

int is_prime(unsigned int number)
{
        if (number <= 1) return 0;
        unsigned int i;
        for (i=2; i*i<=number; i++) {
                if (number % i == 0) return 0;
        }
        return 1;
}
void lemoine(unsigned int n)
{
        unsigned int q, p;
        for (q = n/2; q > 0; q--) {
                p = n - 2 * q;
                if (is_prime(p) && is_prime(q)) {
                        printf("%d = %d + 2*%dn", n, p, q);
                        return;
                }
        }
}

void guess(unsigned int lower, unsigned int upper, unsigned int cores)
{
        unsigned int n;
        boost::asio::io_service svc;
        boost::asio::io_service::work work(svc);
        boost::thread_group threadpool;
        for (int i = 0; i < cores; i++) {
                threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &svc));
        }
        for (n = lower; n <= upper; n+=2) {
                svc.post(std::bind(lemoine, n));
        }
        threadpool.join_all();
}

我已经从在线找到的各种示例一起将其拼凑在一起。问题是threadpool.join_all()永远不会返回。从印刷输出中,我可以看到我所有的工作都完成了,但仍然挂起。我发现的一个例子建议在加入之前发出svc.stop(),但这使输出无法预测,因为它显然在完成之前就杀死了工作(而不是等待它们完成)。我如何确保所有工作完成,并在拥有时保释?

您的代码挂在io_service::run的呼叫上,因为您创建了io_service::work对象(工作参考)。io_service::run仅当调用work的驱动器时才可以返回 - 在您的情况下是不可能的,因为在join_all之后调用工作的DTOR(当功能范围不超出范围时)。您可以通过在Heap上创建work实例来解决此问题(然后您可以手动删除此对象,workio_service::run的DTOR可以返回):

void guess(unsigned int lower, unsigned int upper, unsigned int cores)
{
        unsigned int n;
        boost::asio::io_service svc;
        std::unique_ptr<boost::asio::io_service::work> work =     // ADDED
           std::make_unique<boost::asio::io_service::work>(svc); // ADDED
        boost::thread_group threadpool;
        for (int i = 0; i < cores; i++) {
                threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &svc));
        }
        for (n = lower; n <= upper; n+=2) {
                svc.post(std::bind(lemoine, n));
        }
        work.reset(); // delete work, ADDED
        threadpool.join_all();
}

删除work后,work.reset()完成工作后,您的线程结束。