2

セマフォとマルチスレッドについて学習しようとしています。私が取り組んでいる例では、各スレッドが次のスレッドを指し、最後のスレッドが最初のスレッドを指している 1 から t のスレッドを作成します。このプログラムは、すべてのスレッドが n 回転するまで、各スレッドが順番に回転できるようにします。それはプログラムが終了するときです。唯一の問題は tFunc 関数にあります。私は特定のスレッドの番になるまで待つのに忙しいのです。セマフォを使用してすべてのスレッドをスリープ状態にし、実行する番になったときにのみスレッドを起動して効率を向上させる方法を知りたいです。

int turn = 1;
int counter = 0;
int t, n;

struct tData {
        int me;
        int next;
};

void *tFunc(void *arg) {
        struct tData *data;
        data = (struct tData *) arg;
        for (int i = 0; i < n; i++) {
            while (turn != data->me) {
        }
        counter++;
        turn = data->next;
    }
}

int main (int argc, char *argv[]) {
    t = atoi(argv[1]);
    n = atoi(argv[2]);
    struct tData td[t];
    pthread_t threads[t];
    int rc;

    for (int i = 1; i <= t; i++) {
        if (i == t) {
            td[i].me = i;
            td[i].next = 1;
        }
        else {
            td[i].me = i;
            td[i].next = i + 1;
        }
        rc = pthread_create(&threads[i], NULL, tFunc, (void *)&td[i]);
        if (rc) {
            cout << "Error: Unable to create thread, " << rc << endl;
            exit(-1);
        }
    }
    for (int i = 1; i <= t; i++) {
        pthread_join(threads[i], NULL);
    }
    pthread_exit(NULL);
}
4

3 に答える 3

3

ミューテックスと条件変数を使用します。これが実際の例です:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

int turn = 1;
int counter = 0;
int t, n;

struct tData {
        int me;
        int next;
};

pthread_mutex_t mutex;
pthread_cond_t cond;

void *tFunc(void *arg)
{
    struct tData *data;
    data = (struct tData *) arg;
    pthread_mutex_lock(&mutex);
    for (int i = 0; i < n; i++)
    {
        while (turn != data->me)
            pthread_cond_wait(&cond, &mutex);
        counter++;
        turn = data->next;
        printf("%d goes (turn %d of %d), %d next\n", data->me, i+1, n, turn);
        pthread_cond_broadcast(&cond);
    }
    pthread_mutex_unlock(&mutex);
}

int main (int argc, char *argv[]) {
    t = atoi(argv[1]);
    n = atoi(argv[2]);
    struct tData td[t + 1];
    pthread_t threads[t + 1];
    int rc;

    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    for (int i = 1; i <= t; i++)
    {
        td[i].me = i;
        if (i == t)
            td[i].next = 1;
        else
            td[i].next = i + 1;

        rc = pthread_create(&threads[i], NULL, tFunc, (void *)&td[i]);
        if (rc)
        {
            printf("Error: Unable to create thread: %d\n", rc);
            exit(-1);
        }
    }
    void *ret;
    for (int i = 1; i <= t; i++)
        pthread_join(threads[i], &ret);
}
于 2012-11-26T04:45:23.737 に答える
0

スレッドごとに1つのセマフォがあります。各スレッドをそのセマフォに配置し、が返さwaitれた場合は再試行します。作業が完了したら、次のスレッドのセマフォに移動します。これにより、一度に1つのスレッドのみをウェイクアップすることで、Davidのソリューションの「雷の群れ」の動作を回避できます。sem_waitEINTRpost

また、セマフォの値が1より大きいことはないpthread_mutex_tため、これにaを使用できることにも注意してください。

于 2012-11-26T10:21:12.050 に答える
0

N+1セマフォを使用します。起動時に、スレッドiは semaphore で待機しiます。目が覚めると「and signals semaphorei+1ターン」します。

メイン スレッドは、スレッドNを生成し、セマフォ 0 を通知し、セマフォを待機しNます。

擬似コード:

sem s[N+1];

thread_proc (i):
  repeat N:
      wait (s [i])
      do_work ()
      signal (s [i+1])

main():
  for i in 0 .. N:
    spawn (thread_proc, i)

  repeat N:    
      signal (s [0]);
      wait (s [N]);
于 2012-11-26T10:09:26.607 に答える