2011-12-07 3 views
1

스레드를 모니터링하고 싶습니다. 내가 보낼 & HeartBeat & 수신 확인을위한 조건 변수를 사용했습니다.
scnMonitor_t는 모니터 구조입니다. 새 스레드가 추가되면 모니터 &이 scnThreadlist_t에 추가되어 등록됩니다. monitorHeartbeatCheck는 프로그램으로 시작하는 스레드이고 monitorHeartbeatProcess는 모든 스레드 함수에 추가되는 API입니다.하트 비트 신호를 사용하는 스레드 모니터링

사실 내 문제는 프로세스의 인덱스가 제대로 뒤 따르지 않는다는 것입니다. 3rd 스레드에 대해 대기 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

항상 한 번에 하나의 뮤텍스 만 조건과 연결해야합니다. 같은 조건에서 두 개의 서로 다른 뮤텍스를 동시에 사용하면 응용 프로그램에서 예기치 않은 직렬화 문제가 발생할 수 있습니다.

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에서 뮤텍스를 가져와 조건 변수 인 heartbeatCond에서 sognal을 기다립니다. 따라서 두 스레드는 조건 변수 heartbeatCond에서 대기하여 교 x 상태를 야기합니다. 두 개의 뮤텍스를 사용하는 것이 매우 특이한 경우 왜 두 개의 조건 변수가 필요하지 않습니까?

+0

흠 .. 아쇽이 좋은 생각이야. 나는 그것을 지금 시도했지만 교착 상태를 막을 수는 없다. 나는 내가 사용하는 논리에 뭔가 문제가 있다고 생각한다. 신호는 대기가 준비되기 전에 보내진다. 타이밍이 맞지 않을 수도있다. –

관련 문제