7

OSXでコードをビルドしようとしているので、pthread_timedjoin_npへの依存を取り除く方法を見つけようとしています。

現在、ポップ元のスレッドのキューがあり、そのpthread_timedjoin_npを実行しています。スレッドが戻らない場合は、キューにプッシュバックされます。

各スレッドに対して呼び出されるthread_functionの終わりは、pthread_exit(0)を実行します。受信スレッドがゼロの戻り値をチェックできるようにします。

同様の効果を達成するためにpthread_cond_timedwait()を使用しようと思うかもしれませんが、ステップが欠落していると思います。

ワーカースレッドAのシグナルを条件にし、ミューテックス内のpthread_exit()、、およびワーカースレッドBがシグナルでウェイクアップしてから、pthread_join()を作成できると思いました。問題は、スレッドBがどのスレッドが条件付きシグナルをスローしたかを知らないことです。条件信号の一部として明示的に渡す必要がありますか、それとも何ですか?

ありがとう

デレク

4

3 に答える 3

6

これは、の移植可能な実装ですpthread_timedjoin_np。少しコストがかかりますが、完全なドロップインの代替品です。

struct args {
    int joined;
    pthread_t td;
    pthread_mutex_t mtx;
    pthread_cond_t cond;
    void **res;
};

static void *waiter(void *ap)
{
    struct args *args = ap;
    pthread_join(args->td, args->res);
    pthread_mutex_lock(&args->mtx);
    args->joined = 1;
    pthread_mutex_unlock(&args->mtx);
    pthread_cond_signal(&args->cond);
    return 0;
}

int pthread_timedjoin_np(pthread_t td, void **res, struct timespec *ts)
{
    pthread_t tmp;
    int ret;
    struct args args = { .td = td, .res = res };

    pthread_mutex_init(&args.mtx, 0);
    pthread_cond_init(&args.cond, 0);
    pthread_mutex_lock(&args.mtx);

    ret = pthread_create(&tmp, 0, waiter, &args);
    if (!ret)
            do ret = pthread_cond_timedwait(&args.cond, &args.mtx, ts);
        while (!args.joined && ret != ETIMEDOUT);

    pthread_mutex_unlock(&args.mtx);

    pthread_cancel(tmp);
    pthread_join(tmp, 0);

    pthread_cond_destroy(&args.cond);
    pthread_mutex_destroy(&args.mtx);

    return args.joined ? 0 : ret;
}

これをその場で書いてテストしなかったので、小さなエラーがあるかもしれませんが、コンセプトは健全です。

于 2012-07-19T00:18:46.150 に答える
2

生産者/消費者キュー。スレッドを自分自身でキューに入れ、その結果(存在する場合)をキューに入れてから終了します。キューで待ちます。

ポーリングもレイテンシーもありません。

現在の設計では、返されたスレッドをjoin()して、valueptrを取得し、それらが確実に破棄されるようにする必要があります。

たぶん、タスクアイテムが決して終了しないスレッドにキューイングされる実際のスレッドプールに移動することができます(したがって、スレッドの作成/終了/破棄のオーバーヘッドを排除します)?

于 2012-07-19T06:11:30.707 に答える
0

を使用したソリューションalarm

pthreadはキャンセルを有効にする必要があるため、外部で停止できます(を使用してもpthread_timedjoin_np)。

pthread_timedjoin_npETIMEOUTしばらく待ってから戻ってきます。

  1. セットalarm、使用alarmは「タイムアウト」信号を与えることもできます。
  2. ハンドラーでは、それだけpthread_cancelです。(タイムアウトのみがこれを実行します)。
  3. pthread_joinメインスレッドでそれ。
  4. リセットalarm

私はここにテストコードを書きます:github

于 2015-10-25T01:49:14.193 に答える