2012-01-12 9 views
1

ミューテックスをロックしている同じスレッドがミューテックスをロック解除する必要があることを読んだ。以下のシナリオを考えてみましょう。pthread mutex 2つのスレッドが相互にロック/アンロックするのは有効なアプローチですか?

私はミューテックス変数myMuteT1T2が2つのスレッドであるとします。

  1. T1は、myMuteをロックします。

  2. T2myMuteをロック解除します。

  3. T2ロックmyMute

  4. T1myMuteをロック解除します。

これは、異なるスレッドからのロック/アンロックを有効にする順序ですか?

+2

いいえ、これは、コードセクションがコードの別のセクションで中断されないようにするためのミューテックスを持つという全目的に反します。読んでいると、ロックされたコードだけがロックされるべきです。あなたは別の問題を抱えているように思えます。実際の問題を投稿し、正しい解決策を求めてください。 –

+0

「しなければならない」は、控えめな表現です。ミューテックスは、現在そのスレッドを保持しているスレッドによってのみロックが解除されます。別のスレッドによってロック解除しようとすると、潜在的に非常に危険な未定義の動作が発生します。 –

+0

"有効なアプローチ"とは何ですか?あなたは本当に何をしようとしていますか? –

答えて

5

いいえ、これは間違っています。 pthread_mutex_lockからのmanページ:

スレッドがロックされていないmutexやロック解除されたmutex、未定義の動作結果のロックを解除しようとした場合。

例正しい順序:T1はmyMutex(T2は現在ミューテックスをロック)

  • のロックを解除myMutex
  • T2ロックmyMutex(T1は、ミューテックスのロックを解除するのを待つブロック)
    • T1ロックT2はmyMutexのロックを解除します

    EDIT:

    簡潔のために省略エラーチェックとpthread_cond_wait()を使用して小さな例:

    gcc -Wall -Werror -D_GNU_SOURCE main.c -o main -pthreadでコンパイル
    #include <stdio.h> 
    #include <string.h> 
    #include <stdlib.h> 
    #include <unistd.h> 
    #include <pthread.h> 
    
    volatile int value = 0; 
    pthread_mutex_t mymutex; 
    pthread_t thread_one; 
    pthread_t thread_two; 
    pthread_cond_t cond; 
    
    void* main_one(void* ignored) 
    { 
        while (value < 10) 
        { 
         pthread_mutex_lock(&mymutex); 
         pthread_cond_wait(&cond, &mymutex); 
         fprintf(stderr, "T1: value=%d\n", value); 
         pthread_mutex_unlock(&mymutex); 
        } 
        return (void*)0; 
    } 
    
    void* main_two(void* ignored) 
    { 
        int i; 
    
        for (i = 0; i < 10; i++) 
        { 
         pthread_mutex_lock(&mymutex); 
         value++; 
         fprintf(stderr, "T2: value=%d\n", value); 
         pthread_cond_broadcast(&cond); 
         fprintf(stderr, "Broadcasted but T1 cannot continue for 1 second\n"); 
         sleep(1); 
         pthread_mutex_unlock(&mymutex); 
         pthread_yield(); 
        } 
    
        return (void*)0; 
    } 
    
    void start_thread(void* (*a_entry_point)(void*), 
            pthread_t* a_handle) 
    { 
        pthread_attr_t thread_attributes; 
    
        pthread_attr_init(&thread_attributes); 
        pthread_attr_setdetachstate(&thread_attributes, PTHREAD_CREATE_JOINABLE); 
        pthread_create(a_handle, &thread_attributes, a_entry_point, 0); 
    } 
    
    int main() 
    { 
        pthread_mutexattr_t attr; 
        pthread_t thread_one_handle; 
        pthread_t thread_two_handle; 
    
        /* Init mutex. */ 
        pthread_mutexattr_init(&attr); 
        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); 
        pthread_mutex_init(&mymutex, &attr); 
    
        /* Init condition. */ 
        pthread_cond_init(&cond, 0); 
    
        /* Start threads. */ 
        start_thread(main_one, &thread_one_handle); 
        start_thread(main_two, &thread_two_handle); 
    
        /* Wait for threads. */ 
        pthread_join(thread_one_handle, 0); 
        pthread_join(thread_two_handle, 0); 
    
        /* Clean up. */ 
        pthread_cond_destroy(&cond); 
        pthread_mutex_destroy(&mymutex); 
    
        return 0; 
    } 
    

  • +0

    1)よく、pthread_cond_waitを例に挙げてみましょう。関連するミューテックスのロックを解除し、受信信号を受信して​​からロックします。 2)。ミューテックスを使用してフラグを設定し、条件変数に信号を送ることができます。 3)。私はマーク、ジェフリー、アレックスによる4.4の同期とクリティカルセッションの章で、同じコードが提供されている高度なlinuxプログラミングを読んでいます。同じmutex変数を使用して条件フラグを設定し、同じmutexをwait on condition変数に関連付けます。私は私の質問を適切に伝えたらいいと思う。:) – Whoami

    +2

    mutexをロックした状態で 'pthread_cond_wait'を呼び出さなければなりません。 – hmjd

    +0

    はい、真実ですが、pthread_cond_waitは自動的にmutexのロックを解除し、待機が終了するとロックします。フラグを変更するのを待っているオブジェクトの間で、同じミューテックスの権利を使用できますか?それは質問で言及されたシナリオです。 :)。 – Whoami

    関連する問題