5

こんにちは、マルチスレッドプログラミングの初心者です。スレッド THREAD1 を作成するコードを作成しようとしています。スレッドが何かを実行した後、THREAD2 と THREAD3 などの他の 2 つのスレッドをトリガーして終了します。

私は2つの可能な解決策を書きました。

1) 条件変数の使用 (機能しません: 場合によってはデッドロックが発生します):

pthread_mutex_t ready_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  ready_cond  = PTHREAD_COND_INITIALIZER;
bool ready = false;

void* trigger(void*);
void* func1(void*);
void* func2(void*);

int main()
{
    pthread_t thread1;
    pthread_t thread2;
    pthread_t thread3;  
    pthread_create(&thread1, 0, &trigger, 0);
    pthread_create(&thread2, 0, &func1, 0);
    pthread_create(&thread3, 0, &func2, 0);
    pthread_join(thread1, 0);
    pthread_join(thread2, 0);
    pthread_join(thread3, 0);
}

void *trigger(void*)
{
    pthread_mutex_lock(&ready_mutex);
    ready = true;
    pthread_cond_broadcast(&ready_cond);
    pthread_mutex_unlock(&ready_mutex);
    return 0;
}

void *func1(void*)
{
    while (!ready) // Needed to avoid spuriuos wake-up
    {
        pthread_mutex_lock(&ready_mutex);
        pthread_cond_wait(&ready_cond, &ready_mutex);
        pthread_mutex_unlock(&ready_mutex);
    }
    std::cout << "In 'func1'>> Do something" << std::endl;
    return 0;
}

void *func2(void*)
{
    while (!ready) // Needed to avoid spuriuos wake-up
    {
        pthread_mutex_lock(&ready_mutex);
        pthread_cond_wait(&ready_cond, &ready_mutex);
        pthread_mutex_unlock(&ready_mutex);
    }
    std::cout << "In 'func2'>> Do something" << std::endl;
    return 0;
}

2) THREAD1 は、他の 2 つのスレッドを直接作成します。

pthread_mutex_t ready_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  ready_cond  = PTHREAD_COND_INITIALIZER;

pthread_t thread1;
pthread_t thread2;
pthread_t thread3;

void* trigger(void*);
void* func1(void*);
void* func2(void*);

int main()
{
    pthread_create(&thread1, 0, &trigger, 0);

    pthread_join(thread1, 0);
    pthread_join(thread2, 0);
    pthread_join(thread3, 0);
}

void *trigger(void*)
{
    std::cout << "In 'trigger'>> Do something" << std::endl;

    pthread_create(&thread2, 0, &func1, 0);
    pthread_create(&thread3, 0, &func2, 0);

    return 0;
}

void *func1(void*)
{
    std::cout << "In 'func1'>> Do something" << std::endl;

    return 0;
}

void *func2(void*)
{
    std::cout << "In 'func2'>> Do something" << std::endl;

    return 0;
}

あなたの意見を知りたいです。どうもありがとうございました

4

1 に答える 1

5

条件変数の使用 (機能しません: 場合によってはデッドロックが発生します):

共有変数の状態をチェックするとき、コードはミューテックスをロックしませんready。それがロックされると、ミューテックスreadyはその時までに十分に変更されている可能性があります。これがデッドロックが発生する理由です。

条件変数を使用して状態の変更を待機する正しいバージョンは次のとおりです (エラー チェックは省略されています)。

pthread_mutex_lock(&ready_mutex);
while(!ready) // Needed to avoid spuriuos wake-up
    pthread_cond_wait(&ready_cond, &ready_mutex);
// ready == true here
pthread_mutex_unlock(&ready_mutex);

上記はready、同じミューテックスが保持されている場合にのみ変更されることを前提としています。

于 2012-10-22T20:51:35.970 に答える