Мониторинг потока в c с помощью сигналов сердцебиения - PullRequest
1 голос
/ 07 декабря 2011

Я хочу отслеживать темы. Для этого я использовал условные переменные для отправки и получения сигналов HeartBeat и Acknowledgement.
scnMonitor_t - это структура монитора. По мере добавления новых тем он регистрируется на мониторе и добавляется в scnThreadlist_t. monitorHeartbeatCheck - это поток, который начинается с программы, monitorHeartbeatProcess - это API, который добавляется ко всем функциям потока.

На самом деле моя проблема в том, что индекс процесса не соблюдается должным образом Он заканчивается условием ожидания HB для 3-го потока и создается мертвая блокировка. в чем должна быть проблема?
заранее спасибо.

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;
}

Ответы [ 2 ]

1 голос
/ 08 декабря 2011

Я думаю, что вы попали в тупик здесь. Поток, вызывающий monitorHeartbeatProcess (), принимает мьютекс в heartbeatMutex и ожидает сигнала от условной переменной heartbeatCond. В то время как поток, вызывающий monitorHeartbeatCheck (), принимает мьютекс в ackMutex и ожидает sognal в условной переменной heartbeatCond. Таким образом, оба потока ожидают условную переменную heartbeatCond, вызывающую взаимоблокировку. Если вы так внимательно относитесь к использованию двух мьютексов, почему бы не две условные переменные?

1 голос
/ 07 декабря 2011

Вы должны всегда связывать только один мьютекс с условием одновременно.Использование двух разных мьютексов с одинаковыми условиями в одно и то же время может привести к непредсказуемым проблемам сериализации в вашем приложении.

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

У вас есть 2 разных мьютекса с вашим условием heartbeatCond.

...