2011-12-07 12 views
1

スレッドを監視したい。私は& send HeartBeat &を受け取るための条件変数を使用しました。
scnMonitor_tはモニター構造体です。新しいスレッドが追加されると、scnThreadlist_tにモニタ&が追加されて登録されます。 monitorHeartbeatCheckは、プログラムで始まるスレッドです。 monitorHeartbeatProcessは、すべてのスレッド関数に追加されるAPIです。ハートビート信号を使用したスレッドモニタリング

実際に私の問題は、プロセスのインデックスが正しく追従していないことです。 第3スレッドの待機HB状態で終了します。&デッドロックが作成されました。 何が問題になるはずですか?
ありがとうございます。

typedef struct scnThreadList_{ 
     osiThread_t  thread; 
     struct scnThreadList_ *next; 
} scnThreadList_t; 

typedef struct scnMonitor_{ 
     bool   started; 
     osiThread_t  heartbeatThread; 
     osiMutex_t  heartbeatMutex; 
     osiMutex_t  ackMutex; 
     osiCond_t  heartbeatCond; 
     scnThreadList_t *threads; 
} scnMonitor_t; 
static scnMonitor_t *s_monitor = NULL; 

// Main heartbeat check thread 
void* monitorHeartbeatCheck(void *handle) 
{ 
     scnThreadList_t *pObj = NULL; 
     static int idx = 0; 
     static bool waitAck = false; 

     while (1) { 
       pObj = s_monitor->threads; 
     while (pObj && (pObj != s_monitor->heartbeatThread)) { //skip it-self from monitoring. 
       ++idx; 
       printf("\"HB Check No.%d\"\n",idx); 
       // send heartbeat 
       usleep(250 * 1000); 
       pthread_mutex_lock(s_monitor->heartbeatMutex, 1); 
       pthread_cond_signal(s_monitor->heartbeatCond);  
       printf("-->C %d HB sent\n",idx); 
       pthread_mutex_unlock(s_monitor->heartbeatMutex); 
       // wait for ACK 
       while(!waitAck){ 
         pthread_mutex_lock(s_monitor->ackMutex, 1); 
         printf("|| C %d wait Ack\n",idx); 
         waitAck = true; 
         pthread_cond_wait(s_monitor->heartbeatCond, s_monitor->ackMutex); 
         waitAck = false; 
         printf("<--C %d received Ack\n",idx); 
         pthread_mutex_unlock(s_monitor->ackMutex); 
         LOG_INFO(SCN_MONITOR, "ACK from thread %p \n", pObj->thread); 
       } 
         pObj = pObj->next; 
       } 
     } // while, infinite 
     return NULL; 
} 

// Waits for hearbeat and acknowledges 
// Call this API from every thread function that are registered 
int monitorHeartbeatProcess(void) 
{ 
     static int id = 0; 
     static bool waitHb = false; 
     ++ id; 
     printf("\"HB Process No.%d\"\n",id); 
     // wait for HB 
     while(!waitHb){ 
       pthread_mutex_lock(s_monitor->heartbeatMutex, 1); 
       printf("|| P %d wait for HB\n",id); 
       waitHb = true; 
       pthread_cond_wait(s_monitor->heartbeatCond, s_monitor->heartbeatMutex); 
       waitHb = false; 
       printf("<--P %d HB received \n",id); 
       pthread_mutex_unlock(s_monitor->heartbeatMutex); 
     } 
     // send ACK 
     uleep(250 * 1000); 
     pthread_mutex_lock(s_monitor->ackMutex, 1); 
     pthread_cond_signal(s_monitor->heartbeatCond); 
     printf("-->P %d ACK sent\n",id); 
     pthread_mutex_unlock(s_monitor->ackMutex); 
     return 1; 
} 

答えて

1

一度に1つの条件に必ず1つのミューテックスを関連付ける必要があります。同じ条件の2つの異なるミューテックスを同時に使用すると、アプリケーションで予測できないシリアル化の問題が発生する可能性があります。

http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp?topic=%2Fapis%2Fusers_78.htm

あなたの条件heartbeatCondとの2つの異なるミューテックスを持っています。

+0

私はHB&ACS両方の信号に同じミューテックスを使用すると、それもロック解除できて無駄だと思っていました。 –

1

ここでデッドロックが発生していると思います。 monitorHeartbeatProcess()を呼び出すスレッドは、heartbeatMutexでmutexを受け取り、条件変数heartbeatCondの信号を待ちます。 monitorHeartbeatCheck()を呼び出すスレッドがackMutexでmutexを受け取り、sognal on条件変数、heartbeatCondを待ちます。したがって、両方のスレッドは、条件変数heartbeatCondで待機し、デッドロックを引き起こします。あなたが2つのミューテックスを使用することで非常に特殊なのであれば、なぜ2つの条件変数はありませんか?

+0

うーん。それは良いアイディアだ。私は今それを試したが、デッドロックを止めることはできない。私は何かが私が使用したロジックに間違っていると思う。シグナルが待機準備が整う前に送信されます。タイミングミスマッチかもしれません。 –

関連する問題