Ich habe die Funktion clock_gettime () überprüft, um die aktuelle Zeit abzurufen und die Verarbeitungszeit in der Linux-Umgebung zu messen, und habe sie zusammengefasst.
#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 */
};
Sie können die Zeitinformationen gemäß dem in clk_id angegebenen Uhrentyp abrufen. Auszüge aus den Hauptuhrentypen.
CLOCK_REALTIME Echtzeit. Betroffen von Systemzeitänderungen.
CLOCK_MONOTONIC Verstrichene Zeit ab einem bestimmten Startpunkt. Es ist nicht von Systemzeitänderungen betroffen. Der Startpunkt ist nicht genau angegeben, aber es ist normalerweise die verstrichene Zeit seit dem Einschalten der Stromversorgung.
CLOCK_BOOTTIME Entspricht CLOCK_MONOTONIC, enthält jedoch die Zeit, zu der es angehalten wird.
CLOCK_PROCESS_CPUTIME_ID Vom eigenen Prozess verbrauchte CPU-Zeit (von jedem Thread verbrauchte Gesamt-CPU-Zeit)
CLOCK_THREAD_CPUTIME_ID CPU-Zeit, die vom eigenen Thread verbraucht wird
Erstellen Sie einen Quellcode, um zu sehen, welche Zeitinformationen tatsächlich für jeden ausgegeben werden. Der Quellcode und das Ausführungsbeispiel sind unten dargestellt.
Wenn die Verarbeitung in einem Multithread ausgeführt wird, werden jede Verarbeitungsstartzeit, Verarbeitungsendzeit und ihre verstrichene Zeit (Differenz) bestätigt.
#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;
//----------------------------------------------------------
//Zeitbezogen
//----------------------------------------------------------
//Zeitspezifikationsdifferenzberechnungsfunktion
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;
}
}
//Zeitprotokollklasse
class TimeLog
{
private:
struct timespec real;
struct timespec mono;
struct timespec boot;
struct timespec pcpu;
struct timespec tcpu;
public:
//Aktuelle Zeit abrufen
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;
}
//Einstellung der verstrichenen Zeit
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;
}
//Protokollausgabe
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;
//Ordentliche Verarbeitung
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);
}
//Schwere Verarbeitung
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);
}
//Die tatsächliche Verarbeitung ist nur im Ruhezustand leicht
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);
}
//----------------------------------------------------------
//Hauptverarbeitung
//----------------------------------------------------------
int main(void)
{
//Start der Hauptgewindemessung
TimeLog main_start = TimeLog().getTime().printLog("Main START");
//Fadenstart
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);
//Warten auf das Ende des Threads
pthread_join(tids[0], NULL);
pthread_join(tids[1], NULL);
pthread_join(tids[2], NULL);
//Ende der Hauptgewindemessung
TimeLog main_end = TimeLog().getTime().printLog("Main END ");
elapsed_main.setElapsedTime(main_start, main_end);
//Protokoll anzeigen
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 Kerne
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
Für CLOCK_REALTIME
(real) wird die Unix-Epochenzeit angegeben.
CLOCK_THREAD_CPUTIME_ID
(tcpu) ist die vom entsprechenden Thread verbrauchte CPU-Zeit, sodass die verstrichene Zeit von Thread_C
, die nur schläft, fast 0 beträgt.
Da "CLOCK_PROCESS_CPUTIME_ID" (pcpu) die von allen Threads verbrauchte CPU-Zeit ist, liegt "Main" nahe an der Summe der Thread-CPU-Zeit von "Thread_A" 7.957 "und der Thread-CPU-Zeit" 15.932 "von" Thread_B ". Ich bin.
https://www.mm2d.net/main/prog/c/time-05.html https://linuxjm.osdn.jp/html/LDP_man-pages/man2/clock_gettime.2.html
Recommended Posts