шутка sean.bright получила меня думающий..., почему бы не использовать...
* * * * * /my/script
... и в рамках сценария делают это...
#!/bin/bash
export WHEN=`date '+%M'`
echo $WHEN
export DOIT=`echo "$WHEN % 5" | bc`
echo $DOIT
if [ $DOIT != 0 ] ; then
echo "ha ha ha"
fi
echo "done"
... клудж..., возможно, но столь же ужасный как crontab... Я не знаю.
Я написал пример регистрации вызовов просто для удовольствия. Макрос изменяет вызов функции на инструментальный.
include <stdio.h>.
int funcA( int a, int b ){ return a+b; }
// instrumentation
void call_log(const char*file,const char*function,const int line,const char*args){
printf("file:%s line: %i function: %s args: %s\n",file,line,function,args);
}
#define funcA(...) \
(call_log(__FILE__, __FUNCTION__, __LINE__, "" #__VA_ARGS__), funcA(__VA_ARGS__)).
// testing
void funcB(void){
funcA(7,8);
}
int main(void){
int x = funcA(1,2)+
funcA(3,4);
printf( "x: %i (==10)\n", x );
funcA(5,6);
funcB();
}
Вывод:
file:main.c line: 22 function: main args: 1,2
file:main.c line: 24 function: main args: 3,4
x: 10 (==10)
file:main.c line: 28 function: main args: 5,6
file:main.c line: 17 function: funcB args: 7,8
Скомпилируйте с параметром -pg, запустите программу на некоторое время, а затем используйте gprof. При запуске программы, скомпилированной с параметром -pg, будет создан файл gmon.out с профилем выполнения. gprof может прочитать этот файл и представить его в удобочитаемой форме.
Поскольку вы упомянули oprofile в другом комментарии, я скажу, что oprofile поддерживает создание графов вызовов в профилированных программах.
См. http://oprofile.sourceforge.net/doc/ opreport.html # opreport-callgraph для получения дополнительных сведений.
Стоит отметить, что это определенно не так ясно, как профиль вызывающих абонентов, который вы можете получить от gprof или другого профилировщика, поскольку числа, которые он сообщает, являются количеством раз, когда oprofile собрал образец, в котором X является вызывающим для данной функции, а не количество раз, когда X вызывает данную функцию. Но этого должно быть достаточно, чтобы выяснить, кто чаще всего вызывает данную функцию.
Несколько громоздкий метод, но не требующий дополнительных инструментов:
#define COUNTED_CALL( fn, ...) do{ \
fprintf( call_log_fp, "%s->%s\n", __FUNCTION__, #fn ) ; \
(fn)(__VA_ARGS__) ; \
}while(0) ;
Затем все вызовы, записанные как:
int input_available = COUNTED_CALL( scanf, "%s", &instring ) ;
, будут регистрироваться в файле, связанном с call_log_fp (глобальный ФАЙЛ *, который вы должны инициализированы). Журнал для вышеуказанного будет выглядеть так:
main->scanf
Затем вы можете обработать этот файл журнала для извлечения необходимых данных. Вы даже можете написать свой собственный код для инструментария, который, возможно, сделает его менее громоздким.
Однако может быть немного двусмысленным для функций-членов класса C ++. Я не уверен, существует ли макрос __CLASS__.
In addition to the aforementioned gprof profiler, you may also try the gcov code-coverage tool. Information on compiling for and using both should be included in the gcc manual.
И снова выборка стека на помощь ! Просто сделайте кучу "стекшотов", сколько хотите. Отбросьте все образцы, в которых ваша функция (назовите ее F) не находится где-то в стеке. (Если вы отбрасываете большинство из них, тогда F не является проблемой производительности.)
На каждом оставшемся образце найдите вызов F и посмотрите, в какой функции (назовите ее G) этот вызов. Если F - рекурсивный (он встречается более одного раза в образце) используйте только самый верхний вызов.
Оцените свои G по количеству стеков, в которых появляется каждый.
Если вы не хотите делать это вручную, вы можете сделать простой инструмент или скрипт. Вам не нужен миллион образцов. Примерно 20 дадут вам достаточно хорошую информацию.
Между прочим, , если вы действительно пытаетесь найти проблемы с производительностью, вы этого не сделаете. На самом деле нужно делать все это отбрасывание и ранжирование. Фактически - не отбрасывайте точное расположение инструкции вызова внутри каждого G. Это может сказать вам немного больше, чем просто факт, что они были где-то внутри G.
PS Все это основано на предположении, что когда вы говорите «называет это чаще всего», вы имеете в виду «тратит больше всего времени на вызовы настенных часов», а не «вызывает наибольшее количество раз». Если вас интересует производительность, доля времени настенных часов более полезна, чем счетчик вызовов.
Все это основано на предположении, что когда вы говорите «вызывает наибольшее количество раз», вы имеете в виду «тратит больше всего времени на вызовы настенных часов», а не «вызывает наибольшее количество раз». Если вас интересует производительность, доля времени настенных часов более полезна, чем счетчик вызовов. Все это основано на предположении, что когда вы говорите «вызывает наибольшее количество раз», вы имеете в виду «тратит больше времени на вызовы настенных часов», а не «вызывает наибольшее количество раз». Если вас интересует производительность, доля времени настенных часов более полезна, чем счетчик вызовов.