c - 使用apr thread_pool调度时APR加入线程池线程

标签 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的示例项目,我可以引用。文档非常有限。

非常感谢您的建议,

最佳答案

短雁

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

首先回答你的最后一个问题:我没有找到示例,但 libapr 和 libapr-util 是开源的,你可以阅读源代码,这就是我所做的:(我检查了 SVN-trunk here 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-function-argument(我们稍后将看到)来清理。

现在回到函数apr_pool_cleanup_run,最终调用cleanup_fn

真正的操作是在传递给apr_pool_cleanup_run的函数指针上进行的。因此,如果我们返回到 apr_thread_pool.c:329,我们会找到函数 thread_pool_cleanup。

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

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

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

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

当您调用apr_thread_pool_destroy时,所有线程都会在函数返回之前完全停止。

关于c - 使用apr thread_pool调度时APR加入线程池线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14641792/

相关文章:

c - 用于读取数据库的损坏的 C 代码

java - 使用 ThreadPoolExecutor 取消 SwingWorker

java - 在不同的线程中启动不同的插件

java - 当我们需要实现 Runnable 以及子类 Thread 时的场景

c# - 使用串行端口通信发送批量消息

java - 加载大文件时tomcat重启超时

c - 用C中的信号灯和信号同步过程

c++ - USB 磁盘写入延迟 (windows)

c++ - 为什么预处理器区分数字和字符标记?

java - LinkedBlockingQueue unbounded 和 LinkedBlockingQueue with capacity 哪个更好