3
gcc 4.7.2
c89
apr utility 1.4

こんにちは、

スレッドプールを使用してスレッドを開始しています。ただし、スレッドが参加するのを待つことができる apr 関数が表示されません。

コード sippet では、すべてのエラー チェックと重要でない部分が削除されています。

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 utity 関数は見当たりませんでした。

ただし、この関数は見つかりましたが、引数としてapr_thread_join(apr_status_t *retval, apr_thread_t *thd)aを取ります。apr_thread_t

関数 timeout_duration には時間がかかりますが、apr_thread_t参加に使用する必要がある場合、どうすればそれを返すことができますか?

補足質問です。apr を使用するサンプル プロジェクトはありますか?参照できます。ドキュメントは非常に限られています。

ご提案いただきありがとうございます。

4

1 に答える 1

4

短い答え

スレッドプール内のスレッドに参加する必要はありません。関数を呼び出すとapr_thread_pool_destroy、すべてのスレッドが現在のタスクを完了するまでブロックされます。

あなたの最後の質問に最初に答えるために:私は例を見つけませんでしたが、libaprとlibapr-utilはオープンソースです、あなたはソースを読むことができます、そしてこれは私がしたことです:(私はここでSVNトランクをチェックしましたrev 1441871)

長い答え

興味深いファイル:

最初にチェックインしapr_thread_pool.c:394ます。ここに、の実装がありapr_thread_pool_destroyます。3つの引数で呼び出される関数を呼び出すことがわかりますapr_pool_cleanup_run。1つはpool-storage、1つはthread-pool-context、最後の1つは関数への関数ポインター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

その中で、context-variableは1に設定され、関数は0になるterminatedまで「スリープ」しています。_myself->thd_cnt

の使用法terminatedを検索すると、が0でないthread_pool_funcときにループを終了していることがわかります。これ は、スレッドプール内の各スレッドが使用している関数であることがわかります。ループでは、タスクがフェッチされて実行されます。ループが終了すると(1になったため)、次のコードが実行されます。terminatedthread_pool_functerminated

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

これにより、最終的にはthd_cnt == 0になります。これは、のループの終了条件ですthread_pool_cleanup

呼び出すとapr_thread_pool_destroy、関数が戻る前にすべてのスレッドが完全に停止します。

于 2013-02-03T08:12:46.927 に答える