2012-03-17 68 views
0

デッドロックを回避するために、スレッドがキャンセルされるとmutexをロック解除する必要があります。pthread_mutex_trylockとpthread_mutex_unlockが原因でセグメンテーションフォルトが発生する

// file_a.c 
pthread_attr_t attr; 
... 
rc2 = pthread_attr_init(&attr); 
ERR_IF(rc2 != 0); 
rc2 = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 
ERR_IF(rc2 != 0); 
rc2 = pthread_create(&destroy_thread, &attr, destroy_expired_sessions, NULL); 
ERR_IF(rc2 != 0); 
... 
pthread_attr_destroy(&attr); 

static void *destroy_expired_sessions(void *t) 
{ 
    ... 
    (void)t; 

    pthread_cleanup_push(cleanup_handler, NULL); 
    while (1) 
    { 
      ... // doing some work here 

      sleep(min_timeout); 
    } 
    pthread_cleanup_pop(0); 
} 

static void cleanup_handler(void *arg) 
{ 
    (void)arg; 

    authSessionListMutexUnlock(); 
} 

// file_b.c 
typedef struct 
{ 
    /** Mutex for using this structure. */ 
    pthread_mutex_t mutex; 
    /** The list of Session nodes. */ 
    cList *list; 
} SessionList; 

SessionList *globalSessionList = NULL; 

... 

void authSessionListMutexUnlock() 
{ 
    if (pthread_mutex_trylock(&globalSessionList->mutex) == EBUSY) 
     pthread_mutex_unlock(&globalSessionList->mutex); 
} 

理由は、私はpthread_mutex_trylockのを(使用)ここではmutexがどこかアンロックされている場合()は、第2のpthread_mutex_unlockのを避けるためです。だから私は、次の方法を考案しました。

ただし、ここでpthread_mutex_trylock()およびpthread_mutex_lock()がセグメンテーション違反を引き起こしました。

しかし、ここのプログラムは無害なようですね。

答えて

1

あなたはinitialize your mutex using pthread_mutex_init()に忘れてしまいました。

経験から、初期化されていないミューテックスを使用することは、プログラムをクラッシュさせるかなり安全な賭けです。

別のオプションは、ロックしたスレッド以外のスレッドからmutexのロックを解除しようとしている場合です。その操作の動作は未定義です。

編集:trylockのクイック発言/ unlock;ミューテックスがロックされている場合は、EBUSYを取得しロックを解除します。ミューテックスが解放されている場合、ロックが解除されロックされません。言い換えれば、mutexのロック/アンロック状態をトグルします。それは本当にあなたが意図したとおりですか?

+0

ミューテックスを使用する前に、最初に '私は、初期化コードを一覧表示するには忘れてしまったが、ミューテックスは、' pthread_mutex_initので初期化取得ん()&(globalSessionList->ミューテックス、&mutexAttr)。 –

+0

ところで、ログには、 'pthread_mutex_tunlock()'が実行される前に、 'pthread_mutex_trylock()'で起こったセグメンテーションフォールトが表示されます。 –

+0

@QiangXu私が言うことができる限り、trylock()がクラッシュする唯一の方法は、実際のミューテックスに初期化や何らかの種類のメモリ破損があるかどうかを確認することです。それは失敗)(ロック解除した場合は、ミューテックスが別のスレッドにロックされた可能性がありますし、1つのスレッドでロックが、未定義の動作中に、別の結果にロックを解除するので、それは失敗します。 –

関連する問題