J'ai vérifié la fonction clock_gettime () utilisée pour obtenir l'heure actuelle et mesurer le temps de traitement dans l'environnement Linux, donc je l'ai résumé.
#include <time.h>
int clock_gettime(clockid_t clk_id, struct timespec *tp);
struct timespec {
__kernel_time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
Vous pouvez obtenir les informations d'heure en fonction du type d'horloge spécifié dans clk_id. Extraits des principaux types d'horloge.
CLOCK_REALTIME Temps réel. Affecté par les changements d'heure système.
CLOCK_MONOTONIC Temps écoulé depuis un certain point de départ. Il n'est pas affecté par les changements d'heure système. Le point de départ n'est pas strictement spécifié, mais il s'agit généralement du temps écoulé depuis la mise sous tension.
CLOCK_BOOTTIME Identique à CLOCK_MONOTONIC, mais inclut l'heure à laquelle il est suspendu.
CLOCK_PROCESS_CPUTIME_ID Temps CPU consommé par son propre processus (temps CPU total consommé par chaque thread)
CLOCK_THREAD_CPUTIME_ID Temps CPU consommé par son propre thread
Créez un code source pour voir à quelle heure les informations sont réellement produites pour chacun. Le code source et l'exemple d'exécution sont présentés ci-dessous.
Lorsque le traitement est effectué en multi-thread, chaque heure de début de traitement, heure de fin de traitement et leur temps écoulé (différence) sont confirmés.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/times.h>
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
//----------------------------------------------------------
//Lié au temps
//----------------------------------------------------------
//fonction de calcul de différence de temps
inline void sub_timespec(struct timespec* res, const struct timespec* a, const struct timespec* b)
{
if (a->tv_nsec >= b->tv_nsec) {
res->tv_nsec = a->tv_nsec - b->tv_nsec;
res->tv_sec = a->tv_sec - b->tv_sec;
} else {
res->tv_nsec = 1000000000 + a->tv_nsec - b->tv_nsec;
res->tv_sec = a->tv_sec - b->tv_sec - 1;
}
}
//Classe de journal de temps
class TimeLog
{
private:
struct timespec real;
struct timespec mono;
struct timespec boot;
struct timespec pcpu;
struct timespec tcpu;
public:
//Obtenir l'heure actuelle
TimeLog& getTime() {
clock_gettime(CLOCK_REALTIME, &real);
clock_gettime(CLOCK_MONOTONIC, &mono);
clock_gettime(CLOCK_BOOTTIME , &boot);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &pcpu);
clock_gettime(CLOCK_THREAD_CPUTIME_ID , &tcpu);
return *this;
}
//Réglage du temps écoulé
TimeLog& setElapsedTime(const TimeLog& start, const TimeLog& end) {
sub_timespec(&real, &end.real, &start.real);
sub_timespec(&mono, &end.mono, &start.mono);
sub_timespec(&boot, &end.boot, &start.boot);
sub_timespec(&pcpu, &end.pcpu, &start.pcpu);
sub_timespec(&tcpu, &end.tcpu, &start.tcpu);
return *this;
}
//Sortie de journal
TimeLog& printLog(const char* label) {
pthread_mutex_lock(&g_mutex);
printf("%16s", label);
printf(": real=%ld.%09ld", real.tv_sec, real.tv_nsec);
printf(", mono=%ld.%09ld", mono.tv_sec, mono.tv_nsec);
printf(", boot=%ld.%09ld", boot.tv_sec, boot.tv_nsec);
printf(", pcpu=%ld.%09ld", pcpu.tv_sec, pcpu.tv_nsec);
printf(", tcpu=%ld.%09ld", tcpu.tv_sec, tcpu.tv_nsec);
printf("\n");
pthread_mutex_unlock(&g_mutex);
return *this;
}
};
//----------------------------------------------------------
TimeLog elapsed_main;
TimeLog elapsed_A;
TimeLog elapsed_B;
TimeLog elapsed_C;
//Traitement ordinaire
void* thread_A(void* param)
{
TimeLog start = TimeLog().getTime().printLog("Thread_A START");
for (int64_t ans = 0, i = 0; i <= 1000000000; i++) ans += i;
TimeLog end = TimeLog().getTime().printLog("Thread_A END ");
elapsed_A.setElapsedTime(start, end);
}
//Traitement lourd
void* thread_B(void* param)
{
TimeLog start = TimeLog().getTime().printLog("Thread_B START");
for (int64_t ans = 0, i = 0; i <= 2000000000; i++) ans += i;
TimeLog end = TimeLog().getTime().printLog("Thread_B END ");
elapsed_B.setElapsedTime(start, end);
}
//Le traitement réel est léger uniquement avec Sleep
void* thread_C(void* param)
{
TimeLog start = TimeLog().getTime().printLog("Thread_C START");
sleep(5);
TimeLog end = TimeLog().getTime().printLog("Thread_C END ");
elapsed_C.setElapsedTime(start, end);
}
//----------------------------------------------------------
//Traitement principal
//----------------------------------------------------------
int main(void)
{
//Début de la mesure du fil principal
TimeLog main_start = TimeLog().getTime().printLog("Main START");
//Début du fil
pthread_t tids[3];
pthread_create(&tids[0], NULL, thread_A, NULL);
pthread_create(&tids[1], NULL, thread_B, NULL);
pthread_create(&tids[2], NULL, thread_C, NULL);
//En attente de la fin du fil
pthread_join(tids[0], NULL);
pthread_join(tids[1], NULL);
pthread_join(tids[2], NULL);
//Fin de la mesure du filetage principal
TimeLog main_end = TimeLog().getTime().printLog("Main END ");
elapsed_main.setElapsedTime(main_start, main_end);
//Afficher le journal
printf("\nElapsed Time:\n");
elapsed_main.printLog("Main");
elapsed_A.printLog("Thread_A");
elapsed_B.printLog("Thread_B");
elapsed_C.printLog("Thread_C");
return 0;
}
4 noyaux
Main START: real=1575812537.439121016, mono=32063.696304893, boot=32063.696308226, pcpu=0.004150000, tcpu=0.004155886
Thread_A START: real=1575812537.439749506, mono=32063.696932913, boot=32063.696936038, pcpu=0.004697188, tcpu=0.000063125
Thread_B START: real=1575812537.439850391, mono=32063.697033799, boot=32063.697034945, pcpu=0.004892084, tcpu=0.000040885
Thread_C START: real=1575812537.440102943, mono=32063.697286351, boot=32063.697287705, pcpu=0.005163542, tcpu=0.000039270
Thread_C END : real=1575812542.440262790, mono=32068.697446093, boot=32068.697448385, pcpu=9.990084615, tcpu=0.000146666
Thread_A END : real=1575812545.398370708, mono=32071.655553959, boot=32071.655556043, pcpu=15.896352351, tcpu=7.957370441
Thread_B END : real=1575812553.410668627, mono=32079.667851930, boot=32079.667854222, pcpu=23.895293170, tcpu=15.932487989
Main END : real=1575812553.410906544, mono=32079.668089847, boot=32079.668092139, pcpu=23.895542597, tcpu=0.005018229
Elapsed Time:
Main: real=15.971785528, mono=15.971784954, boot=15.971783913, pcpu=23.891392597, tcpu=0.000862343
Thread_A: real=7.958621202, mono=7.958621046, boot=7.958620005, pcpu=15.891655163, tcpu=7.957307316
Thread_B: real=15.970818236, mono=15.970818131, boot=15.970819277, pcpu=23.890401086, tcpu=15.932447104
Thread_C: real=5.000159847, mono=5.000159742, boot=5.000160680, pcpu=9.984921073, tcpu=0.000107396
Pour CLOCK_REALTIME
(réel), l'heure de l'époque Unix est donnée.
CLOCK_THREAD_CPUTIME_ID
(tcpu) est le temps CPU consommé par le thread correspondant, donc le temps écoulé de Thread_C
, qui ne fait que dormir, est presque 0.
Puisque CLOCK_PROCESS_CPUTIME_ID
(pcpu) est le temps CPU consommé par tous les threads, Main
est proche de la somme du temps CPU du thread Thread_A`` 7,957
et du temps CPU du thread Thread_B`` 15,932
. Je suis.
https://www.mm2d.net/main/prog/c/time-05.html https://linuxjm.osdn.jp/html/LDP_man-pages/man2/clock_gettime.2.html