C таймеры и темы снова - PullRequest
1 голос
/ 17 января 2011

Может ли кто-нибудь помочь мне дополнить мой код функцией, которая может проверять результат таймера "check_timer", и другой, которая сбрасывает этот таймер, если срок его действия истек "reset_timer"?

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <sys/time.h>

#define GLOBAL_TIMER  8 * 60 * 60


typedef struct protocol_type {
 int protocol_number;
 char *protocol_name;
 pthread_t thread_timer_id;
} protocol_type_t;

pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;


/* call back function - inform the user the time has expired */
void timeout_call_back(pthread_t thread_id)
{
    printf("Welcome thread %ld, your time is up ===\n", pthread_self());
    // doing some other stuff
}

/* Go to sleep for a period of seconds */
static void* start_timer(void *args)
{
    /* function pointer */
    void (*finish_function)(pthread_t);


    int seconds = *((int*) args);

    finish_function = timeout_call_back;

 struct timeval now;
 struct timespec timeout;

 pthread_mutex_lock(&mut);
 printf("thread ID : %ld, are waiting for %d seconds to to expire\n", pthread_self(), seconds);
 gettimeofday(&now, NULL);
 timeout.tv_sec = now.tv_sec + seconds;
 timeout.tv_nsec = now.tv_usec * 1000;
 pthread_cond_timedwait(&cond, &mut, &timeout);
 (*finish_function)(pthread_self());
 pthread_mutex_unlock(&mut);
    pthread_exit(NULL);
}

// This function is in MT environnement and is running inside a daemon
int received_buffer_parser(char *received_buffer) {
 pthread_mutex_t mut_main = PTHREAD_MUTEX_INITIALIZER; 
 protocol_type_t *my_protocol;

 // Identify protocol type
 my_protocol = protocol_identifier(received_buffer);

 // Check if i received it in the last 8 hours in safe 
 pthread_mutex_lock(&mut_main);
    if (check_timer(my_protocol->thread_id) has expired) { // I want to write this function
  // I want to reset thread timer
   launch_new_timer(my_protocol->thread_id)
 }
 else {
  // doing some stuff
  // dump data to the disk
 }
 pthread_mutex_unlock(&mut_main);

 return 0;
}

int launch_new_timer(pthread_t thread_id)
{
 int rc;
 int seconds = GLOBAL_TIMER;

    rc =  pthread_create(&thread_id, NULL, start_timer, (void *) &seconds);
    if(rc)
     printf("Failed to create thread1\n");

    pthread_join(thread_id, NULL);

    return 0;
}

Разъяснение

Я разъясняю реальный контекст моего кода: Я получаю из сети несколько типов пакетов различных протоколов (ICMP, SSH, RIP, OSPF, BGP ...) и хочу:

  1. идентифицирует каждый тип пакетов, скажем, с помощью: identif_protocol (char * receive_buffer), я получил эту функцию, все в порядке.

  2. Проверьте, получаю ли я этот тип протоколов за последние 8 часов (ТАЙМЕР КАЖДОГО ТИПА ПРОТОКОЛА, ПОСЛЕ 8 ЧАСОВ), два варианта:

а. в этом случае я вывожу данные результатов в определенный файл на диске.

б. нет, я не получал этот тип за последние 8 ЧАСОВ. Я создаю новый поток (в моем коде я упрощаю, с потоками 1, потоком 2 и потоком 3, эти потоки - это 3 потока, используемые как таймеры для трех типов протоколов) - я запустить новый таймер с помощью функции: start_timer (void * args), выполняющей эту работу.

Мой главный вопрос - как можно безопасно проверить результаты моих таймеров и затем решить, сбросить ли я таймер или нет.

Вначале я создаю функцию finish_, чтобы помочь мне проверить, истек ли таймер.

Не стесняйтесь, дайте мне лучший дизайн для лучших выступлений для моей программы.

Моя система - Linux.

1 Ответ

2 голосов
/ 17 января 2011

Чтобы проверить таймеры, которые просто истекают, вам вообще не нужно использовать потоки и синхронизацию.Просто сохраните глобальные переменные, указывающие время запуска таймера.Поэтому

  • при запуске таймера установите глобальную переменную (по одной на протокол) на gettimeofday ()
  • , когда вы хотите проверить, истек ли таймер для протокола, посмотрите,gettimeofday () - время начала (протокол): <8h </li>

Если вы хотите получать уведомления об истечении таймера, я рекомендую использовать сигнализацию (2).У него только второе разрешение, но этого должно хватить на 8 часов.Всякий раз, когда таймер установлен, отменен или сброшен, вычислите минимальное время ожидания любого из таймеров, затем вызовите сигнал тревоги с этим временем ожидания.В обработчике сигнала выполните обработку, которую вы хотите выполнить при получении тайм-аута.В качестве альтернативы, ничего не делайте в обработчике сигналов и просто верьте, что любой ожидающий системный вызов будет прерван, и проверьте все таймеры на истечение срока действия в EINTR.

Редактировать : сигнал тревоги работает следующим образом

#include <unistd.h>
#include <signal.h>
void timeout(int ignored)
{
   printf("timed out\n");
}

void main()
{
    signal(SIGALRM, timeout);
    alarm(10);
    pause();
}
...