Bagaimana mengukur waktu dalam milidetik menggunakan ANSI C?


127

Hanya menggunakan ANSI C, adakah cara untuk mengukur waktu dengan presisi milidetik atau lebih? Saya sedang menjelajah time.h tetapi saya hanya menemukan fungsi presisi kedua.


4
Perhatikan perbedaan antara presisi dan akurasi. Anda bisa mendapatkan waktu dengan ketepatan milidetik dengan mencatat waktu dalam detik dan mengalikannya dengan 1000, tapi itu tidak ada gunanya. Fungsi presisi ms tidak selalu memiliki akurasi ms - meskipun umumnya memiliki akurasi yang lebih baik daripada akurasi 1s.
Steve Jessop

2
Jawaban sederhananya adalah TIDAK, ANSI C tidak mendukung presisi milidetik atau lebih baik. Jawaban yang lebih kompleks tergantung pada apa yang Anda coba lakukan - terus terang seluruh area adalah mimpi buruk - bahkan jika Anda mengizinkan penggunaan fungsi Posix yang banyak tersedia. Anda menggunakan istilah "mengukur" jadi saya berasumsi bahwa Anda tertarik pada interval daripada waktu "jam dinding". Tetapi apakah Anda mencoba mengukur periode waktu absolut atau penggunaan cpu dengan proses Anda?
Dipstick

2
Hanya ingin mengatakan kepada SOF baru saja menyelamatkan daging saya, sekali lagi ;-)
corlettk

Jawaban:


92

Tidak ada fungsi ANSI C yang memberikan resolusi waktu lebih baik dari 1 detik, tetapi fungsi POSIX gettimeofdaymenyediakan resolusi mikrodetik. Fungsi jam hanya mengukur jumlah waktu yang dihabiskan suatu proses untuk dieksekusi dan tidak akurat pada banyak sistem.

Anda dapat menggunakan fungsi ini seperti ini:

struct timeval tval_before, tval_after, tval_result;

gettimeofday(&tval_before, NULL);

// Some code you want to time, for example:
sleep(1);

gettimeofday(&tval_after, NULL);

timersub(&tval_after, &tval_before, &tval_result);

printf("Time elapsed: %ld.%06ld\n", (long int)tval_result.tv_sec, (long int)tval_result.tv_usec);

Ini mengembalikan Time elapsed: 1.000870mesin saya.


30
Sedikit peringatan: gettimeofday () tidak monoton, artinya gettimeofday () dapat melompat-lompat (dan bahkan mundur) jika, misalnya, mesin Anda mencoba untuk menjaga sinkronisasi dengan server waktu jaringan atau sumber waktu lain.
Dipstick

3
Tepatnya: Dalam ISO C99 (yang menurut saya kompatibel di bagian ini dengan ANSI C) bahkan tidak ada jaminan resolusi waktu apa pun . (ISO C99, 7.23.1p4)
Roland Illig

6
Perlu dicatat bahwa timeval::tv_usecselalu di bawah satu detik, itu berulang. Yaitu untuk mengambil perbedaan waktu lebih besar dari 1 detik, Anda harus:long usec_diff = (e.tv_sec - s.tv_sec)*1000000 + (e.tv_usec - s.tv_usec);
Alexander Malakhov

4
@Dipstick: Tapi perhatikan bahwa misalnya NTP tidak pernah memundurkan jam Anda sampai Anda secara eksplisit menyuruhnya melakukannya.
thejh

1
Logika pengurangan waktu @AlexanderMalakhov diinkapsulasi di dalam timersubfungsi. Kita dapat menggunakan tval_resultnilai (tv_sec dan tv_usec) apa adanya.
x4444

48
#include <time.h>
clock_t uptime = clock() / (CLOCKS_PER_SEC / 1000);

CLOCKS_PER_SEC disetel ke 1000000 di banyak sistem. Cetak nilainya untuk memastikan sebelum Anda menggunakannya dengan cara ini.
ysap

16
Karena itu jam per detik, tidak masalah berapa nilainya, nilai yang dihasilkan dari clock () / CLOCKS_PER_SEC akan dalam hitungan detik (setidaknya seharusnya). Membagi dengan 1000 mengubahnya menjadi milidetik.
David Young

14
Menurut C Reference Manual, nilai clock_t dapat dimulai sekitar 36 menit. Jika Anda mengukur komputasi yang lama, Anda perlu menyadari hal ini.
CyberSkull

4
Juga berhati-hatilah bahwa pembagian integer CLOCKS_PER_SEC / 1000mungkin tidak tepat yang dapat mempengaruhi hasil akhir (meskipun menurut pengalaman saya CLOCKS_PER_SECselalu kelipatan 1000). Melakukan (1000 * clock()) / CLOCKS_PER_SECkurang rentan terhadap ketidaktepatan pembagian, tetapi di sisi lain lebih rentan terhadap luapan. Hanya beberapa masalah yang perlu dipertimbangkan.
Cornstalks

4
Bukankah ini mengukur waktu cpu dan bukan waktu dinding?
krs013

28

Saya selalu menggunakan fungsi clock_gettime (), mengembalikan waktu dari jam CLOCK_MONOTONIC. Waktu yang dikembalikan adalah jumlah waktu, dalam detik dan nanodetik, sejak beberapa titik yang tidak ditentukan di masa lalu, seperti permulaan sistem pada zaman tersebut.

#include <stdio.h>
#include <stdint.h>
#include <time.h>

int64_t timespecDiff(struct timespec *timeA_p, struct timespec *timeB_p)
{
  return ((timeA_p->tv_sec * 1000000000) + timeA_p->tv_nsec) -
           ((timeB_p->tv_sec * 1000000000) + timeB_p->tv_nsec);
}

int main(int argc, char **argv)
{
  struct timespec start, end;
  clock_gettime(CLOCK_MONOTONIC, &start);

  // Some code I am interested in measuring 

  clock_gettime(CLOCK_MONOTONIC, &end);

  uint64_t timeElapsed = timespecDiff(&end, &start);
}

5
clock_gettime () bukan ANSI C.
PowerApp101

1
CLOCK_MONOTONIC juga tidak diimplementasikan pada banyak sistem (termasuk banyak platform Linux).
Dipstick

2
@ PowerApp101 Tidak ada cara ANSI C yang baik / kuat untuk melakukan ini. Banyak dari jawaban lain mengandalkan POSIX daripada ANCI C. Meski begitu, saya percaya hari ini. @Dipstick Hari ini, saya yakin sebagian besar platform modern [butuh rujukan] mendukung clock_gettime(CLOCK_MONOTONIC, ...)dan bahkan ada makro uji fitur _POSIX_MONOTONIC_CLOCK.
omninonsense

22

Menerapkan solusi portabel

Seperti yang telah disebutkan di sini bahwa tidak ada solusi ANSI yang tepat dengan ketepatan yang cukup untuk masalah pengukuran waktu, saya ingin menulis tentang cara mendapatkan portabel dan, jika mungkin, solusi pengukuran waktu resolusi tinggi.

Jam monotonik vs stempel waktu

Secara umum ada dua cara pengukuran waktu:

  • jam monotonik;
  • stempel waktu saat ini (tanggal).

Yang pertama menggunakan penghitung jam monotonik (terkadang disebut penghitung tick) yang menghitung tick dengan frekuensi yang telah ditentukan, jadi jika Anda memiliki nilai tick dan frekuensinya diketahui, Anda dapat dengan mudah mengubah tick ke waktu yang telah berlalu. Sebenarnya tidak ada jaminan bahwa jam monotonik mencerminkan waktu sistem saat ini dengan cara apa pun, ia juga dapat menghitung kutu sejak sistem dinyalakan. Tapi itu menjamin bahwa jam selalu berjalan dengan cara yang meningkat terlepas dari status sistemnya. Biasanya frekuensi terikat ke sumber resolusi tinggi perangkat keras, itulah sebabnya ia memberikan akurasi tinggi (bergantung pada perangkat keras, tetapi sebagian besar perangkat keras modern tidak memiliki masalah dengan sumber jam resolusi tinggi).

Cara kedua memberikan nilai waktu (tanggal) berdasarkan nilai jam sistem saat ini. Ini mungkin juga memiliki resolusi tinggi, tetapi memiliki satu kelemahan utama: nilai waktu semacam ini dapat dipengaruhi oleh penyesuaian waktu sistem yang berbeda, yaitu perubahan zona waktu, perubahan waktu musim panas (DST), pembaruan server NTP, hibernasi sistem, dan sebagainya. di. Dalam beberapa situasi, Anda bisa mendapatkan nilai waktu berlalu yang negatif yang dapat menyebabkan perilaku yang tidak ditentukan. Sebenarnya sumber waktu semacam ini kurang dapat diandalkan dibandingkan yang pertama.

Jadi aturan pertama dalam pengukuran interval waktu adalah menggunakan jam monotonik jika memungkinkan. Biasanya memiliki presisi tinggi, dan desainnya dapat diandalkan.

Strategi fallback

Saat mengimplementasikan solusi portabel, ada baiknya untuk mempertimbangkan strategi fallback: gunakan jam monotonik jika tersedia dan fallback ke pendekatan stempel waktu jika tidak ada jam monotonik dalam sistem.

Windows

Ada artikel bagus berjudul Memperoleh stempel waktu resolusi tinggi di MSDN tentang pengukuran waktu di Windows yang menjelaskan semua detail yang mungkin perlu Anda ketahui tentang dukungan perangkat lunak dan perangkat keras. Untuk mendapatkan cap waktu presisi tinggi di Windows, Anda harus:

  • kueri frekuensi pengatur waktu (ticks per second) dengan QueryPerformanceFrequency :

    LARGE_INTEGER tcounter;
    LARGE_INTEGER freq;    
    
    if (QueryPerformanceFrequency (&tcounter) != 0)
        freq = tcounter.QuadPart;

    Frekuensi pengatur waktu ditetapkan pada boot sistem sehingga Anda hanya perlu mendapatkannya sekali.

  • menanyakan nilai ticks saat ini dengan QueryPerformanceCounter :

    LARGE_INTEGER tcounter;
    LARGE_INTEGER tick_value;
    
    if (QueryPerformanceCounter (&tcounter) != 0)
        tick_value = tcounter.QuadPart;
  • skala tanda ke waktu yang telah berlalu, yaitu ke mikrodetik:

    LARGE_INTEGER usecs = (tick_value - prev_tick_value) / (freq / 1000000);

Menurut Microsoft, Anda seharusnya tidak mengalami masalah dengan pendekatan ini pada Windows XP dan versi yang lebih baru dalam banyak kasus. Tetapi Anda juga dapat menggunakan dua solusi fallback di Windows:

  • GetTickCount memberikan jumlah milidetik yang telah berlalu sejak sistem dimulai. Ini membungkus setiap 49,7 hari, jadi berhati-hatilah dalam mengukur interval yang lebih lama.
  • GetTickCount64 adalah versi 64-bit GetTickCount, tetapi tersedia mulai dari Windows Vista dan yang lebih baru.

OS X (macOS)

OS X (macOS) memiliki satuan waktu absolut Mach sendiri yang mewakili jam monotonik. Cara terbaik untuk memulai adalah artikel Apple Q&A Teknis QA1398: Mach Absolute Time Units yang menjelaskan (dengan contoh kode) bagaimana menggunakan API khusus Mach untuk mendapatkan tanda centang monoton. Ada juga pertanyaan lokal tentang itu yang disebut clock_gettime alternatif di Mac OS X yang pada akhirnya mungkin membuat Anda sedikit bingung apa yang harus dilakukan dengan kemungkinan overflow nilai karena frekuensi penghitung digunakan dalam bentuk pembilang dan penyebut. Jadi, contoh singkat bagaimana mendapatkan waktu yang berlalu:

  • dapatkan pembilang dan penyebut frekuensi clock:

    #include <mach/mach_time.h>
    #include <stdint.h>
    
    static uint64_t freq_num   = 0;
    static uint64_t freq_denom = 0;
    
    void init_clock_frequency ()
    {
        mach_timebase_info_data_t tb;
    
        if (mach_timebase_info (&tb) == KERN_SUCCESS && tb.denom != 0) {
            freq_num   = (uint64_t) tb.numer;
            freq_denom = (uint64_t) tb.denom;
        }
    }

    Anda hanya perlu melakukannya sekali.

  • menanyakan nilai tick saat ini dengan mach_absolute_time:

    uint64_t tick_value = mach_absolute_time ();
  • menskalakan tick ke waktu yang telah berlalu, yaitu ke mikrodetik, menggunakan pembilang dan penyebut yang ditanyakan sebelumnya:

    uint64_t value_diff = tick_value - prev_tick_value;
    
    /* To prevent overflow */
    value_diff /= 1000;
    
    value_diff *= freq_num;
    value_diff /= freq_denom;

    Ide utama untuk mencegah overflow adalah dengan menurunkan tick ke akurasi yang diinginkan sebelum menggunakan pembilang dan penyebut. Karena resolusi pengatur waktu awal dalam nanodetik, kami membaginya 1000untuk mendapatkan mikrodetik. Anda dapat menemukan pendekatan yang sama yang digunakan di time_mac.c Chromium . Jika Anda benar-benar membutuhkan akurasi nanodetik, pertimbangkan untuk membaca bagian Bagaimana cara menggunakan mach_absolute_time tanpa meluap? .

Linux dan UNIX

The clock_gettimepanggilan adalah cara Anda terbaik pada setiap sistem yang ramah POSIX. Itu dapat meminta waktu dari sumber jam yang berbeda, dan yang kita butuhkan adalah CLOCK_MONOTONIC. Tidak semua sistem clock_gettimemendukung CLOCK_MONOTONIC, jadi hal pertama yang perlu Anda lakukan adalah memeriksa ketersediaannya:

  • jika _POSIX_MONOTONIC_CLOCKdidefinisikan ke nilai >= 0itu berarti CLOCK_MONOTONICtersedia;
  • jika _POSIX_MONOTONIC_CLOCKdidefinisikan untuk 0itu berarti Anda juga harus memeriksa apakah itu berfungsi saat runtime, saya sarankan untuk menggunakan sysconf:

    #include <unistd.h>
    
    #ifdef _SC_MONOTONIC_CLOCK
    if (sysconf (_SC_MONOTONIC_CLOCK) > 0) {
        /* A monotonic clock presents */
    }
    #endif
  • jika tidak, jam monotonik tidak didukung dan Anda harus menggunakan strategi fallback (lihat di bawah).

Penggunaannya clock_gettimecukup mudah:

  • dapatkan nilai waktu:

    #include <time.h>
    #include <sys/time.h>
    #include <stdint.h>
    
    uint64_t get_posix_clock_time ()
    {
        struct timespec ts;
    
        if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0)
            return (uint64_t) (ts.tv_sec * 1000000 + ts.tv_nsec / 1000);
        else
            return 0;
    }

    Saya telah memperkecil waktu menjadi mikrodetik di sini.

  • menghitung selisih dengan nilai waktu sebelumnya diterima dengan cara yang sama:

    uint64_t prev_time_value, time_value;
    uint64_t time_diff;
    
    /* Initial time */
    prev_time_value = get_posix_clock_time ();
    
    /* Do some work here */
    
    /* Final time */
    time_value = get_posix_clock_time ();
    
    /* Time difference */
    time_diff = time_value - prev_time_value;

Strategi fallback terbaik adalah menggunakan gettimeofdaypanggilan: ini tidak monotonik, tetapi memberikan resolusi yang cukup baik. Idenya sama dengan dengan clock_gettime, tetapi untuk mendapatkan nilai waktu Anda harus:

#include <time.h>
#include <sys/time.h>
#include <stdint.h>

uint64_t get_gtod_clock_time ()
{
    struct timeval tv;

    if (gettimeofday (&tv, NULL) == 0)
        return (uint64_t) (tv.tv_sec * 1000000 + tv.tv_usec);
    else
        return 0;
}

Sekali lagi, nilai waktu diperkecil menjadi mikrodetik.

SGI IRIX

IRIX punya clock_gettimepanggilan, tapi kurang CLOCK_MONOTONIC. Sebaliknya ia memiliki sumber jam monotoniknya sendiri yang didefinisikan sebagai CLOCK_SGI_CYCLEyang harus Anda gunakan, bukan CLOCK_MONOTONICdengan clock_gettime.

Solaris dan HP-UX

Solaris memiliki antarmuka gethrtimepengatur waktu resolusi tinggi yang mengembalikan nilai pengatur waktu saat ini dalam nanodetik. Meskipun versi Solaris yang lebih baru mungkin memiliki clock_gettime, Anda dapat tetap menggunakannya gethrtimejika Anda perlu mendukung versi Solaris yang lama.

Penggunaannya sederhana:

#include <sys/time.h>

void time_measure_example ()
{
    hrtime_t prev_time_value, time_value;
    hrtime_t time_diff;

    /* Initial time */
    prev_time_value = gethrtime ();

    /* Do some work here */

    /* Final time */
    time_value = gethrtime ();

    /* Time difference */
    time_diff = time_value - prev_time_value;
}

HP-UX tidak memiliki kekurangan clock_gettime, tetapi mendukung gethrtimeyang harus Anda gunakan dengan cara yang sama seperti pada Solaris.

BeOS

BeOS juga memiliki antarmuka system_timepengatur waktu resolusi tinggi yang mengembalikan jumlah mikrodetik yang telah berlalu sejak komputer di-boot.

Contoh penggunaan:

#include <kernel/OS.h>

void time_measure_example ()
{
    bigtime_t prev_time_value, time_value;
    bigtime_t time_diff;

    /* Initial time */
    prev_time_value = system_time ();

    /* Do some work here */

    /* Final time */
    time_value = system_time ();

    /* Time difference */
    time_diff = time_value - prev_time_value;
}

OS / 2

OS / 2 memiliki API sendiri untuk mengambil stempel waktu presisi tinggi:

  • query frekuensi timer (ticks per unit) dengan DosTmrQueryFreq(untuk compiler GCC):

    #define INCL_DOSPROFILE
    #define INCL_DOSERRORS
    #include <os2.h>
    #include <stdint.h>
    
    ULONG freq;
    
    DosTmrQueryFreq (&freq);
  • menanyakan nilai ticks saat ini dengan DosTmrQueryTime:

    QWORD    tcounter;
    unit64_t time_low;
    unit64_t time_high;
    unit64_t timestamp;
    
    if (DosTmrQueryTime (&tcounter) == NO_ERROR) {
        time_low  = (unit64_t) tcounter.ulLo;
        time_high = (unit64_t) tcounter.ulHi;
    
        timestamp = (time_high << 32) | time_low;
    }
  • skala tanda ke waktu yang telah berlalu, yaitu ke mikrodetik:

    uint64_t usecs = (prev_timestamp - timestamp) / (freq / 1000000);

Contoh implementasi

Anda dapat melihat pustaka plibsys yang mengimplementasikan semua strategi yang dijelaskan di atas (lihat ptimeprofiler * .c untuk detailnya).


"tidak ada solusi ANSI yang tepat dengan presisi yang memadai untuk masalah pengukuran waktu": terdapat C11 timespec_get: stackoverflow.com/a/36095407/895245
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

1
Ini masih merupakan cara yang salah untuk mengukur waktu eksekusi kode. timespec_gettidak monotonik.
Alexander Saprykin

11

timespec_get dari C11

Mengembalikan hingga nanodetik, dibulatkan ke resolusi penerapan.

Sepertinya penipuan ANSI dari POSIX ' clock_gettime.

Contoh: a printfdilakukan setiap 100ms di Ubuntu 15.10:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

static long get_nanos(void) {
    struct timespec ts;
    timespec_get(&ts, TIME_UTC);
    return (long)ts.tv_sec * 1000000000L + ts.tv_nsec;
}

int main(void) {
    long nanos;
    long last_nanos;
    long start;
    nanos = get_nanos();
    last_nanos = nanos;
    start = nanos;
    while (1) {
        nanos = get_nanos();
        if (nanos - last_nanos > 100000000L) {
            printf("current nanos: %ld\n", nanos - start);
            last_nanos = nanos;
        }
    }
    return EXIT_SUCCESS;
}

The C11 N1570 standar rancangan 7.27.2.5 "Fungsi timespec_get mengatakan":

Jika basis adalah TIME_UTC, anggota tv_sec disetel ke jumlah detik sejak implementasi menentukan epoch, dipotong ke nilai keseluruhan dan anggota tv_nsec disetel ke jumlah integral nanodetik, dibulatkan ke resolusi jam sistem. (321)

321) Meskipun objek struct timespec mendeskripsikan waktu dengan resolusi nanodetik, resolusi yang tersedia bergantung pada sistem dan bahkan mungkin lebih besar dari 1 detik.

C ++ 11 juga mendapat std::chrono::high_resolution_clock: C ++ Cross-Platform High-Resolution Timer

glibc 2.21

Dapat ditemukan di bawah sysdeps/posix/timespec_get.csebagai:

int
timespec_get (struct timespec *ts, int base)
{
  switch (base)
    {
    case TIME_UTC:
      if (__clock_gettime (CLOCK_REALTIME, ts) < 0)
        return 0;
      break;

    default:
      return 0;
    }

  return base;
}

sangat jelas:

  • hanya TIME_UTCsaat ini didukung

  • itu meneruskan ke __clock_gettime (CLOCK_REALTIME, ts), yang merupakan API POSIX: http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html

    Linux x86-64 memiliki file clock_gettime panggilan sistem.

    Perhatikan bahwa ini bukan metode pembandingan mikro yang terbukti gagal karena:

    • man clock_gettimemengatakan bahwa ukuran ini mungkin memiliki diskontinuitas jika Anda mengubah beberapa pengaturan waktu sistem saat program Anda berjalan. Ini harus menjadi peristiwa yang jarang terjadi, dan Anda mungkin bisa mengabaikannya.

    • ini mengukur waktu dinding, jadi jika penjadwal memutuskan untuk melupakan tugas Anda, tugas itu akan tampak berjalan lebih lama.

    Untuk alasan itu getrusage() mungkin alat pembandingan POSIX yang lebih baik, meskipun presisi maksimum mikrodetiknya lebih rendah.

    Informasi lebih lanjut di: Mengukur waktu di Linux - waktu vs jam vs getrusage vs clock_gettime vs gettimeofday vs timespec_get?


ini adalah jawaban yang benar pada tahun 2017, bahkan MSVC memiliki fungsi ini; dalam hal pembandingan mencari sesuatu yang membaca register chip (versi terbaru dari prosesor x86 dengan ekstensi PT, dan versi terbaru dari kernel / perf Linux)

4

Presisi terbaik yang mungkin Anda peroleh adalah melalui penggunaan instruksi "rdtsc" hanya x86, yang dapat memberikan resolusi level-jam (tentu saja tidak harus memperhitungkan biaya panggilan rdtsc itu sendiri, yang dapat diukur dengan mudah di aplikasi startup).

Tangkapan utama di sini adalah mengukur jumlah jam per detik, yang seharusnya tidak terlalu sulit.


3
Anda mungkin juga perlu mengkhawatirkan afinitas prosesor, karena pada beberapa mesin Anda mungkin mengirim panggilan RDTSC ke lebih dari satu prosesor dan penghitung RDTSC mereka mungkin tidak disinkronkan.
Akankah Dean

1
Dan lebih jauh lagi, beberapa prosesor tidak memiliki TSC yang meningkat secara monoton - pikirkan mode hemat daya yang mengurangi frekuensi CPU. Menggunakan RDTSC untuk apa pun kecuali pengaturan waktu lokal yang sangat singkat adalah ide yang SANGAT buruk.
snemarch

Btw, inti drift yang disebutkan oleh @WillDean dan menggunakan rdtsc untuk pengaturan waktu adalah alasan mengapa sejumlah game gagal bekerja pada CPU AMD64 multi-core (awal?) - Saya harus membatasi ke afinitas inti tunggal pada x2 4400+ saya untuk sejumlah judul.
snemarch

2

Jawaban yang diterima cukup bagus, tetapi solusi saya lebih sederhana, saya hanya menguji di Linux, gunakan gcc (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0.

Alse use gettimeofday, the tv_secadalah bagian dari detik, dan tv_usecadalah mikrodetik , bukan milidetik .

long currentTimeMillis() {
  struct timeval time;
  gettimeofday(&time, NULL);

  return time.tv_sec * 1000 + time.tv_usec / 1000;
}

int main() {
  printf("%ld\n", currentTimeMillis());
  // wait 1 second
  sleep(1);
  printf("%ld\n", currentTimeMillis());
  return 0;
 }

Ini mencetak:

1522139691342 1522139692342, tepat satu detik.


-4

Di bawah jendela:

SYSTEMTIME t;
GetLocalTime(&t);
swprintf_s(buff, L"[%02d:%02d:%02d:%d]\t", t.wHour, t.wMinute, t.wSecond, t.wMilliseconds);

1
apakah ansi C ini sesuai permintaan?
Gyom
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.