使用apr_thread_pool_schedule时APR加入线程池线程

时间:2013-02-01 07:44:30

标签: c multithreading threadpool apr

gcc 4.7.2
c89
apr utility 1.4

您好,

我正在使用线程池来启动线程。但是,我看不到任何允许我等待线程加入的apr函数。

代码片段,删除了所有错误检查和非必要部分:

int main(void)
{
    /* Initialize apr internal structures */
    apr_initialize();

    /* Create memory pool */
    rv = apr_pool_create(&mem_pool, NULL);

    /* Create thread pool */
    memset(&buf, 0, sizeof buf);
    rv = apr_thread_pool_create(&thd_pool,
                                init_threads,
                                max_threads,
                                mem_pool);

    /* Process the number of jobs */
#define NUMBER_JOBS 1
    for(i = 0; i < NUMBER_JOBS; i++) {
        rv = apr_thread_pool_schedule(thd_pool,
                                      timeout_duration,
                                      (void*)channel,
                                      (apr_interval_time_t)flash_timeout,
                                      NULL);

    }

    /* 
     * Join all threads here 
     */

    /* Destroy resources */
    apr_thread_pool_destroy(thd_pool);
    apr_pool_destroy(mem_pool);
    apr_terminate();

    return 0;
error:
    apr_thread_pool_destroy(thd_pool);
    apr_pool_destroy(mem_pool);
    apr_terminate();

    return 1;
}

void* timeout_duration(apr_thread_t *thd, void *data)
{
    channel_t *channel = (channel_t*)data;

    LOG_DEBUG("Channel timeout notification [ %zu ]", channel->id);
}

我看不到任何连接线程的功能。

但是,我确实找到了这个函数apr_thread_join(apr_status_t *retval, apr_thread_t *thd)但是,它需要apr_thread_t作为参数。

函数timeout_duration需要apr_thread_t,但如果我需要使用它来加入,我该如何设法将其传回去?

只是旁注的问题。是否有任何使用apr的示例项目,我可以参考。文档非常有限。

非常感谢任何建议,

1 个答案:

答案 0 :(得分:4)

简短的anser

您不需要加入线程池中的线程。当你调用apr_thread_pool_destroy时,该函数将被阻塞,直到所有线程完成当前任务。

首先回答你的上一个问题:我没有找到一个例子,但是libapr和libapr-util是开源的,你可以阅读源代码,这就是我所做的:(我检查了SVN-trunk {{ 3}} rev 1441871)

答案很长

有趣的文件:

首先检查apr_thread_pool.c:394。在这里,我们找到了apr_thread_pool_destroy的实现。我们可以看到它调用一个名为apr_pool_cleanup_run的函数,其中包含三个参数,一个是池存储,一个是线程池上下文,最后一个是函数指向函数thread_pool_cleanup

如果我们关注apr_pool_cleanup_run,我们会转到apr_pools.c:2453并看到apr_pool_cleanup_kill被调用。阅读这最后一个函数向我们展示,这里在元素(线程)的几个循环中被(我们将在后面看到的)调用cleanup_fn - 函数参数。

现在回到功能apr_pool_cleanup_run,最后一次调用cleanup_fn

实际操作是传递给apr_pool_cleanup_run的函数指针。因此,如果我们返回apr_thread_pool.c:329,我们会找到函数thread_pool_cleanup

在其中,上下文变量terminated设置为1,然后函数“休眠”,直到_myself->thd_cnt变为0。

搜索terminated的使用情况,当thread_pool_func不为0时,我们发现terminated正在退出其循环。事实证明thread_pool_func是每个线程的函数线程池正在使用。在循环中,获取并执行任务。当循环终止时(因为terminated变为1),执行以下代码:

 /* idle thread been asked to stop, will be joined */
 --me->thd_cnt;

这将最终导致thd_cnt == 0,这是thread_pool_cleanup中循环的终止条件。

当你调用apr_thread_pool_destroy时,所有线程都会在函数返回之前干净地停止。