有人可以帮助我用一个可以检查定时器“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 ...),我想:
识别每种类型的数据包,比方说:identify_protocol(char * received_buffer),我有这个功能,没关系。
检查我是否在过去8小时内收到此类协议(8小时后每个协议类型的定时器),有两种选择:
一个。如果是这样,我将结果数据转储到磁盘上的特定文件中。
湾不,我在最后8小时没有收到这种类型我创建了一个新线程(在我的代码中我简化了,使用thread1,thread2和thread3,这个线程是3个线程用来作为三种协议类型的定时器) - 我启动一个新的计时器:start_timer(void * args)函数完成这项工作。
我的主要问题是如何能够以安全的方式检查我的计时器的结果,然后决定是否重置计时器。
我在开头设计了finish_function,以帮助我检查计时器何时到期。
随意给我一个更好的设计,为我的节目提供最佳表现。
我的系统是Linux。
答案 0 :(得分:2)
要检查仅过期的计时器,您根本不需要使用线程和同步。只需保留表示计时器开始时间的全局变量。所以
如果您希望在计时器到期时收到通知,我建议使用闹钟(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();
}