Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在linux中使用计时器记录度量_C_Linux - Fatal编程技术网

C 在linux中使用计时器记录度量

C 在linux中使用计时器记录度量,c,linux,C,Linux,我需要捕获一些指标,比如发送tcp消息的时间和linux上c语言中每秒发送的消息数。 我想知道这是否可以通过定时器来完成,这样每当定时器过期时,我只需打印度量。主要问题是,在度量递增时可能会出现计时器,在这种情况下,我的信号处理程序将打印损坏的数据。有办法解决这个问题吗 所以我心目中的伪代码是声明一个全局结构,它包含每个发送和计数的发送时间 struct db { struct sendTimes sendTimesPerSecond[10000]; // some large number

我需要捕获一些指标,比如发送tcp消息的时间和linux上c语言中每秒发送的消息数。 我想知道这是否可以通过定时器来完成,这样每当定时器过期时,我只需打印度量。主要问题是,在度量递增时可能会出现计时器,在这种情况下,我的信号处理程序将打印损坏的数据。有办法解决这个问题吗

所以我心目中的伪代码是声明一个全局结构,它包含每个发送和计数的发送时间

struct db
{
 struct sendTimes sendTimesPerSecond[10000]; // some large number which i cannot send in a second
 int count;
}
在哪里

然后提供一些可以在structdb上工作的函数,例如

void record_send_time(pointer_to_db, sendTimes); // simply store the times
void incrementMessagesSent(pointer_to_db); //basically count++
然后我可以做一些事情,比如:

signal(SIGALRM, alarm_handler);
alarm(1)
struct db database;

for(;;) {
struct sendTimes sTime;
sTime.start_time = now(); // current time
send()
sTime.end_time = now();
record_send_time(&database, sTime);
incrementMessagesSent(&database); 
}


void alarm_handler(int signo)
{
  printf database;
  alarm(1);
 }
更新:
Wildplasser关于管道的评论似乎是处理上述问题的最安全方式。

您可以使用报警处理程序设置标志,而不是从信号处理程序打印

int print_database_flag = 0; // global flag

  // ...
  record_send_time(&database, sTime);
  if (print_database_flag) {
     printf database;
     print_database_flag = 0;
  }

void alarm_handler(int signo)
{
  print_database_flag = 1;
  alarm(1);
}
使用
getrusage(2)
,它有两个
struct timeval
捕获程序在用户(您的代码)和内核模式(发送等)下使用的时间


我不知道你打算用printf数据库做什么,但我必须警告您,printf()在信号处理程序中不安全。顺便说一句:避免信号处理程序中出现printf或其他争用的最简单方法是使用管道:让信号处理程序写入管道,让main位于select()或poll()循环上。无需锁定/关闭。记住:write()是原子的。@wildplasser在信号处理程序中翻转布尔变量的值是否足够好,如更新:部分中所述?不,您仍然会遇到竞争(谁将重置变量?),和/或main()需要轮询,变量需要是volatile/sig_atomic__t等。太混乱。双重锁定,即,在主处理器和信号处理器中,将导致死锁。您可以使用Reentrant lock,但这样做不会保护全局数据结构被破坏。在该示例中没有锁定,只检查一个标志。我看不到潜在的僵局。最糟糕的情况是,多个alarm()调用将导致高负载下的一次打印,这对于显示getrusage和timersub来说是正确的。我是手工计算的。
int print_database_flag = 0; // global flag

  // ...
  record_send_time(&database, sTime);
  if (print_database_flag) {
     printf database;
     print_database_flag = 0;
  }

void alarm_handler(int signo)
{
  print_database_flag = 1;
  alarm(1);
}
#include <sys/time.h>
#include <sys/resource.h>
struct rusage start, end;
getrusage(RUSAGE_SELF, &start);
// do what you have to do
getrusage(RUSAGE_SELF, &end);

struct timeval utime, stime;
timersub(&end.ru_utime, &start.ru_utime, &utime);
timersub(&end.ru_stime, &start.ru_stime, &stime);
printf("Work took %lu microseconds of user time and %lu microseconds of system time\n",
     (utime.tv_sec * 1000 * 1000) + utime.tv_usec,
     (stime.tv_sec * 1000 * 1000) + stime.tv_usec
     );